Script written by Derek Banas (http://www.newthinktank.com) | Watch the online video tutorial here!
Reorganized by cozyplanes (https://cozyplanes.github.io)
C# Cheatsheet - AdvancedPart 1 - C# Basics1. Namespaces, Main, Input, Output, Loops, Command Line Arguments, Arrays, Data Types, DateTime, TimeSpan, BigInteger, Formatting, Strings, String Functions, and Functions2. Implicit Typing, Casting, For, For Each and Arrays and StringBuilder3. If, Else, Else If, Relational Operators, Logical Operators, Ternary Operator, Switch, Break, Continue, Goto, While Do While, Convert, Try, Catch, Finally and Exception Handling4. Methods, Pass by Value versus Pass by Reference, Out Parameter, Params, Named Parameters, Method Overloading, and Enum5. Classes, Methods, Fields, Constructors, Static Classes, Methods and Fields, Structs and Nullable Types6. public, private, protected, constants, read-only fields, constructors, setters, getters, properties and static7. Protected, Inheritance, Aggregations, Virtual, Override, Super Classes, Inner Classes, New, Base, and Polymorphism8. Break time : Simple OOP Warrior GamePart 2 - C# Advanced9. Abstract Classes, Virtual Methods, Abstract Methods, Override, Base Classes, Is, As, Casting, and more about Polymorphism10. Abstract Methods, Inheriting an Interface, How to Create Flexible Designs, and the Command Design Pattern11. C# Collections : ArrayLists, Dictionaries, Queues, and Stacks12. Generic Collections, Generic Methods, Generic Structs, and Delegates13. Manipulating Lists with LINQ Extension Methods : Lambda, Where, ToList, Select, Zip, Aggregate, Average, All, Any, Distinct, Except, Intersect14. IEnumerable, Indexer, Enumerator, Operator Overloading, Custom Casting, Anonymous Types15. From, Where, Orderby, Select, In, Inner Joins, Group Inner Join, Equals and using LINQ with multiple different collections16. Thread Basics, Sleep, Lock, Priority, Pass Data to a Thread17. File System, File, DirectoryInfo, FileInfo, FileStream, StreamWriter, StreamReader, BinaryWriter, BinaryReader18. Serialization, Serialize, Deserialize, BinaryFormatter, XmlSerializerPart 3 - C# GUI19. WPF, XAML, Properties, MessageBox, Event Handling, Resources, Layout Managers20. Menu Bars, DockPanels, Icons, ScrollViewer, Fonts, Grid Layout21. Toolbars, Toolbar Trays, Combo Boxes, Icons22. Minimal Paint Application (1), Calendar, Tab Controls, Capturing Key Events23. Document API, FlowDocumentReader, FlowDocumentPageViewer, FlowDocumentScrollViewer, RichTextBox24. Minimal Paint Application (2), Canvas, Line, Ellipse, RectanglesPart 4 - C# Misc25. Setup SQL Server, Create Tables, SSMS, Visual Studio 2017, App.config, Connecting to SQL Server with C
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; using System.Numerics; // You use a namespace to define globally unique objectsnamespace CSharpTutA.cs{ // A class defines the variables and methods used // by objects. I'll get more into this later class Program { // The main function is where execution begins // static functions belong to the class and // can be executed without needing to create // an object // void means that this function doesn't return // a value after it executes, but it is // common to use int instead and return an // integer value 0 : when successfully executed // or -1 when an error occurred // This function can receive multiple string // values that are saved into an array static void Main(string[] args) { // Write a string to the console followed // be a newline // Write() doesn't include a newline // The Console class provides functions for input // output and error streams for console applications Console.WriteLine("Hello World"); // for loops allow you to cycle through information // We will get command line arguments passed and print // them for(int i = 0; i < args.Length; i++) { // We use format parameters to place the string // version of passed objects into the output Console.WriteLine("Arg {0} : {1}", i, args[i]); } // Passing command line arguments in Visual Studio // Right click on project name in Solution Explorer // Select Properties // Select Debug tab on the left // Enter parameters in Command Line Arguments textbox // Click Start // Get an array of the command line arguments string[] myArgs = Environment.GetCommandLineArgs(); // Use the Join function to combine arguments with a comma Console.WriteLine(string.Join(", ", myArgs)); // Call for the function to execute // SayHello(); // ---------- DATA TYPES ---------- // Bools store true or false bool canIVote = true; // INTEGERS // Integers are 32-bit signed integers Console.WriteLine("Biggest Integer : {0}", int.MaxValue); Console.WriteLine("Smallest Integer : {0}", int.MinValue); // LONGS // Longs are 64-bit signed integers Console.WriteLine("Biggest Long : {0}", long.MaxValue); Console.WriteLine("Smallest Long : {0}", long.MinValue); // DECIMALS // Decimals store 128-bit precise decimal values // It is accurate to 28 digits decimal decPiVal = 3.1415926535897932384626433832M; decimal decBigNum = 3.00000000000000000000000000011M; Console.WriteLine("DEC : PI + bigNum = {0}", decPiVal + decBigNum); Console.WriteLine("Biggest Decimal : {0}", Decimal.MaxValue); // DOUBLES // Doubles are 64-bit float types Console.WriteLine("Biggest Double : {0}", Double.MaxValue.ToString("#")); // It is precise to 14 digits double dblPiVal = 3.14159265358979; double dblBigNum = 3.00000000000002; Console.WriteLine("DBL : PI + bigNum = {0}", dblPiVal + dblBigNum); // FLOATS // Floats are 32-bit float types Console.WriteLine("Biggest Float : {0}", float.MaxValue.ToString("#")); // It is precise to 6 digits float fltPiVal = 3.141592F; float fltBigNum = 3.000002F; Console.WriteLine("FLT : PI + bigNum = {0}", fltPiVal + fltBigNum); // Other Data Types // byte : 8-bit unsigned int 0 to 255 // char : 16-bit unicode character // sbyte : 8-bit signed int 128 to 127 // short : 16-bit signed int -32,768 to 32,767 // uint : 32-bit unsigned int 0 to 4,294,967,295 // ulong : 64-bit unsigned int 0 to 18,446,744,073,709,551,615 // ushort : 16-bit unsigned int 0 to 65,535 // You can convert from string to other types with Parse bool boolFromStr = bool.Parse("True"); int intFromStr = int.Parse("100"); double dblFromStr = double.Parse("1.234"); // ---------- DATETIME & TIMESPAN ---------- // Used to define dates DateTime awesomeDate = new DateTime(1974, 12, 21); Console.WriteLine("Day of Week : {0}", awesomeDate.DayOfWeek); // You can change values awesomeDate = awesomeDate.AddDays(4); awesomeDate = awesomeDate.AddMonths(1); awesomeDate = awesomeDate.AddYears(1); Console.WriteLine("New Date : {0}", awesomeDate.Date); // TimeSpan // Used to define a time TimeSpan lunchTime = new TimeSpan(12, 30, 0); // Change values lunchTime = lunchTime.Subtract(new TimeSpan(0, 15, 0)); lunchTime = lunchTime.Add(new TimeSpan(1, 0, 0)); Console.WriteLine("New Time : {0}", lunchTime.ToString()); // ---------- BIGINTEGER ---------- // Used to store very large numbers // Select Project -> Add Reference // Select Assemblies -> System.Numerics.dll click Ok // Add this line using System.Numerics; at the top // Define the value using a text literal BigInteger bigNum = BigInteger.Parse("12345123451234512345"); Console.WriteLine("Big Num * 2 = {0}", bigNum * 2); // ---------- FORMATTING OUTPUT ---------- // Format output for currency Console.WriteLine("Currency : {0:c}", 23.455); // Pad with zeroes Console.WriteLine("Pad with 0s : {0:d4}", 23); // Define decimals Console.WriteLine("3 Decimals : {0:f3}", 23.4555); // Add commas and decimals Console.WriteLine("Commas : {0:n4}", 2300); // ---------- STRINGS ---------- // Strings store a series of characters string randString = "This is a string"; // Get number of characters in string Console.WriteLine("String Length : {0}", randString.Length); // Check if string contains other string Console.WriteLine("String Contains is : {0}", randString.Contains("is")); // Index of string match Console.WriteLine("Index of is : {0}", randString.IndexOf("is")); // Remove number of characters starting at an index Console.WriteLine("Remove string : {0}", randString.Remove(10, 6)); // Add a string starting at an index Console.WriteLine("Insert String : {0}", randString.Insert(10, "short ")); // Replace a string with another Console.WriteLine("Replace String : {0}", randString.Replace("string", "sentence")); // Compare strings and ignore case // < 0 : str1 preceeds str2 // = : Zero // > 0 : str2 preceeds str1 Console.WriteLine("Compare A to B : {0}", String.Compare("A", "B", StringComparison.OrdinalIgnoreCase)); // Check if strings are equal Console.WriteLine("A = a : {0}", String.Equals("A", "a", StringComparison.OrdinalIgnoreCase)); // Add padding left Console.WriteLine("Pad Left : {0}", randString.PadLeft(20, '.')); // Add padding right Console.WriteLine("Pad Right : {0} Stuff", randString.PadRight(20, '.')); // Trim whitespace Console.WriteLine("Trim : {0}", randString.Trim()); // Make uppercase Console.WriteLine("Uppercase : {0}", randString.ToUpper()); // Make lowercase Console.WriteLine("Lowercase : {0}", randString.ToLower()); // Use Format to create strings string newString = String.Format("{0} saw a {1} {2} in the {3}", "Paul", "rabbit", "eating", "field"); // You can add newlines with \n and join strings with + Console.Write(newString + "\n"); // Other escape characters // \' \" \\ \t \a // Verbatim strings ignore escape characters Console.Write(@"Exactly What I Typed"); // Excepts input up until a newline, but it is here to // keep the console open after output // Read() excepts a single character Console.ReadLine(); } // You can create your own functions (methods) private static void SayHello() { // Defines a variable that will store a string // of characters string name = ""; Console.Write("What is your name : "); // Save the input the user provides name = Console.ReadLine(); Console.WriteLine("Hello {0}", name); } }} x using System; using System.Collections.Generic; using System.Linq; // Needed for StringBuilder using System.Text; using System.Threading.Tasks; // For culture specific formating using System.Globalization; namespace CSharpTutA.cs { class Program { static void Main(string[] args) { // ----- IMPLICIT TYPING ----- // You can use var to have C# figure out the // data type var intVal = 1234; Console.WriteLine("intVal Type : {0}", intVal.GetType()); // ----- ARRAYS ----- // Arrays are just boxes inside of a bigger box // that can contain many values of the same // data type // Each item is assigned a key starting at 0 // and incrementing up from there // Define an array which holds 3 values // Arrays have fixed sizes int[] favNums = new int[3]; // Add a value to the array favNums[0] = 23; // Retrieve a value Console.WriteLine("favNum 0 : {0}", favNums[0]); // Create and fill array string[] customers = { "Bob", "Sally", "Sue" }; // You can use var to create arrays, but the // values must be of the same type var employees = new[] { "Mike", "Paul", "Rick" }; // Create an array of base objects which is the // base type of all other types object[] randomArray = { "Paul", 45, 1.234 }; // GetType knows its true type Console.WriteLine("randomArray 0 : {0}", randomArray[0].GetType()); // Get number of items in array Console.WriteLine("Array Size : {0}", randomArray.Length); // Use for loop to cycle through the array for(int i = 0; i < randomArray.Length; i++) { Console.WriteLine("Array {0} : Value : {1}", i, randomArray[i]); } // Multidimensional arrays // When you define an array like arrName[5] you // are saying you want to create boxes stacked // vertically // If you define arrName[2,2] you are saying // you want to have 2 rows high and 2 across string[,] custNames = new string[2,2] { { "Bob", "Smith" }, { "Sally", "Smith" } }; // Get value in MD array Console.WriteLine("MD Value : {0}", custNames.GetValue(1,1)); // Cycle through the multidimensional array // Get length of multidimensional array column for (int i = 0; i < custNames.GetLength(0); i++) { // Get length of multidimensional array row for(int j = 0; j < custNames.GetLength(1); j++) { Console.Write("{0} ",custNames[i,j]); } Console.WriteLine(); } // An array like arrName[2,2,3] would be like a // stack of 3 spread sheets with 2 rows and 2 // columns worth of data on each page // foreach can be used to cycle through an array int[] randNums = { 1, 4, 9, 2 }; // You can pass an array to a function PrintArray(randNums, "ForEach"); // Sort array Array.Sort(randNums); // Reverse array Array.Reverse(randNums); // Get index of match or return -1 Console.WriteLine("1 at index : {0} ", Array.IndexOf(randNums, 1)); // Change value at index 1 to 0 randNums.SetValue(0, 1); // Copy part of an array to another int[] srcArray = { 1, 2, 3 }; int[] destArray = new int[2]; int startInd = 0; int length = 2; Array.Copy(srcArray, startInd, destArray, startInd, length); PrintArray(destArray, "Copy"); // Create an array with CreateInstance Array anotherArray = Array.CreateInstance(typeof(int), 10); // Copy values in srcArray to destArray starting // at index 5 in destination srcArray.CopyTo(anotherArray, 5); foreach (int m in anotherArray) { Console.WriteLine("CopyTo : {0} ", m); } // Search for an element that matches the conditions // defined by the specified predicate int[] numArray = { 1, 11, 22 }; Console.WriteLine("> 10 : {0}", Array.Find(numArray, GT10)); // FindAll returns an array with all values that // match // FindIndex returns the index of the match // ----- STRINGBUILDER ----- // Each time you change a string you are actually // creating a new string which is inefficient // when you are working with large blocks of text // StringBuilders actually change the text // rather then make a copy // Create a StringBuilder with a default size // of 16 characters, but it grows automatically StringBuilder sb = new StringBuilder("Random Text"); // Create a StringBuilder with a size of 256 StringBuilder sb2 = new StringBuilder("More Stuff that is very important", 256); // Get max size Console.WriteLine("Capacity : {0}", sb2.Capacity); // Get length Console.WriteLine("Length : {0}", sb2.Length); // Add text to StringBuilder sb2.AppendLine("\nMore important text"); // Define culture specific formating CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US"); // Append a format string string bestCust = "Bob Smith"; sb2.AppendFormat(enUS, "Best Customer : {0}", bestCust); // Output StringBuilder Console.WriteLine(sb2.ToString()); // Replace a string sb2.Replace("text", "characters"); Console.WriteLine(sb2.ToString()); // Clear a string builder sb2.Clear(); sb2.Append("Random Text"); // Are objects equal Console.WriteLine(sb.Equals(sb2)); // Insert at an index sb2.Insert(11, " that's Great"); Console.WriteLine("Insert : {0}", sb2.ToString()); // Remove number of characters starting at index sb2.Remove(11, 7); Console.WriteLine("Remove : {0}", sb2.ToString()); // ----- CASTING ----- // If you want to cast from one type to another long num1 = 1234; int num2 = (int)num1; Console.WriteLine("Orig : {0} Cast : {1}", num1.GetType(), num2.GetType()); Console.ReadLine(); } static void PrintArray(int[] intArray, string mess) { foreach (int k in intArray) { Console.WriteLine("{0} : {1} ", mess, k); } } private static bool GT10(int val) { return val > 10; } } } xxxxxxxxxxusing System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; namespace CSharpTutA.cs{ class Program { static void Main(string[] args) { // ----- CONDITIONALS ----- // ----- IF / ELSE / ----- // Relational Operators : > < >= <= == != // Logical Operators : && || ! int age = 17; if ((age >= 5) && (age <= 7)) { Console.WriteLine("Go to elementary school"); } else if ((age > 7) && (age < 13)) { Console.WriteLine("Go to middle school"); } else if ((age > 13) && (age < 19)) { Console.WriteLine("Go to high school"); } else { Console.WriteLine("Go to college"); } if ((age < 14) || (age > 67)) { Console.WriteLine("You shouldn't work"); } Console.WriteLine("! true = " + (!true)); // Ternary Operator // Assigns the 1st value if true and otherwise // the 2nd bool canDrive = age >= 16 ? true : false; // Switch is used when you have limited options // The only way to use ranges is to stack // the possible values switch (age) { case 1: case 2: Console.WriteLine("Go to Day Care"); break; case 3: case 4: Console.WriteLine("Go to Preschool"); break; case 5: Console.WriteLine("Go to Kindergarten"); break; default: Console.WriteLine("Go to another school"); // You can also jump out of a switch // with goto goto OtherSchool; } OtherSchool: Console.WriteLine("Elementary, Middle, High School"); // To compare strings use Equals string name = "Derek"; string name2 = "Derek"; if (name.Equals(name2, StringComparison.Ordinal)) { Console.WriteLine("Names are Equal"); } // ----- WHILE LOOP ----- // You use the while loop when you want to execute // as long as a condition is true // This while loop will print odd numbers between // 1 and 10 int i = 1; while (i <= 10) { // % (Modulus) returns the remainder of a // division. If it returns 0 that means the // value is even if (i % 2 == 0) { i++; // Continue skips the rest of the code and // starts execution back at the top of the // while continue; } // Break jumps completely out of the loop if (i == 9) break; Console.WriteLine(i); i++; } // ----- DO WHILE LOOP ----- // Use do while when you must execute the code // at least once // Generate a random number Random rnd = new Random(); int secretNumber = rnd.Next(1, 11); int numberGuessed = 0; do { Console.Write("Enter a number between 1 & 10 : "); // Use Convert to switch the string into an int numberGuessed = Convert.ToInt32(Console.ReadLine()); } while (secretNumber != numberGuessed); Console.WriteLine("You guessed it is was {0}", secretNumber); // Other Convert options : ToBoolean, ToByte, // ToChar, ToDecimal, ToDouble, ToInt64, // ToString, and they can convert from any // type to any other type // ----- EXCEPTION HANDLING ----- // We use exception handling to catch errors // that could crash our program double num1 = 5; double num2 = 0; // Code that could cause an error is surrounded // by a try block try { Console.WriteLine("5 / 0 = {0}", DoDivision(num1, num2)); } // We catch the error and warn the user // rather then crash the program catch (DivideByZeroException ex) { Console.WriteLine("You can't Divide by Zero"); // Get additonal info on the exception Console.WriteLine(ex.GetType().Name); Console.WriteLine(ex.Message); } // This is the default catch all for exceptions catch (Exception ex) { Console.WriteLine("An error occurred"); Console.WriteLine(ex.GetType().Name); Console.WriteLine(ex.Message); } // finally always runs and provides for clean up finally { Console.WriteLine("Cleaning Up"); } // Well cover more about exception handling // with some real examples soon Console.ReadLine(); } static double DoDivision(double x, double y) { if(y == 0) { // We are throwing an exception because // you can't divide by zero throw new System.DivideByZeroException(); } return x / y; } }} xxxxxxxxxxusing System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; namespace CSharpTutA.cs{ class Program { static void Main(string[] args) { // ----- PASSING BY VALUE ----- double x = 5; double y = 4; Console.WriteLine("5 + 4 = {0}", GetSum(x, y)); // Even though the value for x changed in // method it remains unchanged here Console.WriteLine("x = {0}", x); // ----- OUT PARAMETER ----- // You can pass a variable as an output // variable even without assigning a // value to it int solution; // A parameter passed with out has its // value assigned in the method DoubleIt(15, out solution); Console.WriteLine("15 * 2 = {0}", solution); // ----- PASS BY REFERENCE ----- int num1 = 10; int num2 = 20; Console.WriteLine("Before Swap num1 : {0} num2 : {1}", num1, num2); Swap(ref num1, ref num2); Console.WriteLine("After Swap num1 : {0} num2 : {1}", num1, num2); // ----- PARAMS ----- // You are able to pass a variable amount // of data of the same data type into a // method using params. You can also pass // in an array. Console.WriteLine("1 + 2 + 3 = {0}", GetSumMore(1, 2, 3)); // ----- NAMED PARAMETERS ----- // You can pass values in any order if // you used named parameters PrintInfo(zipCode: 15147, name: "Derek Banas"); // ----- METHOD OVERLOADING ----- // You can define methods with the same // name that will be called depending on // what data is sent automatically Console.WriteLine("5.0 + 4.0 = {0}", GetSum(5.0, 4.5)); Console.WriteLine("5 + 4 = {0}", GetSum(5, 4)); Console.WriteLine("5 + 4 = {0}", GetSum("5", "4")); // ----- ENUM ----- CarColor car1 = CarColor.Blue; PaintCar(car1); Console.ReadLine(); } // ----- PASS BY VALUE ----- // By default values are passed into a method // and not a reference to the variable passed // Changes made to those values do not effect the // variables outside of the method // If you assign a value then it is optional to // pass static double GetSum(double x = 1, double y = 1) { double temp = x; x = y; y = temp; return x + y; } // ----- OUT PARAMETER ----- // A parameter marked with out must be assigned // a value in the method static void DoubleIt(int x, out int solution) { solution = x * 2; } // ----- PASS BY REFERENCE ----- // If a variable is passed by reference changes // to its value in the method effect it outside // of the method public static void Swap(ref int num1, ref int num2) { int temp = num1; num1 = num2; num2 = temp; } // ----- PARAMS ----- // The params array must be the last parameter // in the list static double GetSumMore(params double[] nums) { double sum = 0; foreach (int i in nums) { sum += i; } return sum; } // ----- NAMED PARAMETERS ----- static void PrintInfo(string name, int zipCode) { Console.WriteLine("{0} lives in the zip code {1}", name, zipCode); } // ----- METHOD OVERLOADING ----- static double GetSum(double x = 1, double y = 1) { return x + y; } static double GetSum(string x = "1", string y = "1") { double dblX = Convert.ToDouble(x); double dblY = Convert.ToDouble(y); return dblX + dblY; } // ----- ENUM ----- // ----- ENUM ----- // An enum is a custom data type with // key value pairs. They allow you to // use symbolic names to represent data // The first number is 0 by default unless // you change it // You can define the underlying type // or leave it as int as default enum CarColor : byte { Orange = 1, Blue, Green, Red, Yellow } static void PaintCar(CarColor cc) { Console.WriteLine("The car was painted {0} with the code {1}", cc, (int)cc); } }} xxxxxxxxxx---------- Program.cs ---------- using System; namespace CSharpTutA.cs{ class Program { static void Main(string[] args) { // Create a Rectangle Rectangle rect1; // Add values to it and run the Area method rect1.length = 200; rect1.width = 50; Console.WriteLine("Area of rect1 : {0}", rect1.Area()); // Use a constructor to create a Rectangle Rectangle rect2 = new Rectangle(100, 40); // If you assign one Rectangle to another // you are setting the values and not // creating a reference rect2 = rect1; rect1.length = 33; Console.WriteLine("rect2.length : {0}", rect2.length); // ----- OBJECT ORIENTED PROGRAMMING ----- // A class models real world objects by // defining their attributes (fields) and // capabilities (methods) // Then unlike with structs you can // inherit from a class and create more // specific subclass types // Add a class Project -> Add Class // Create an Animal object // You could also assign values like // fox.name = "Red" Animal fox = new Animal() { name = "Red", sound = "Raaaw" }; // Call the static method Console.WriteLine("# of Animals {0}", Animal.GetNumAnimals()); // You can also create static utility // classes Project -> Add Class Console.WriteLine("Area of Rectangle : {0}", ShapeMath.GetArea("rectangle", 5, 6)); // ----- NULLABLE TYPES ----- // Data types by default cannot have a // value of null. Often null is needed // when you are working with databases // and you can create a null type by // adding a ? to the definition int? randNum = null; // Check for null if(randNum == null) { Console.WriteLine("randNum is null"); } // Another check for null if (!randNum.HasValue) { Console.WriteLine("randNum is null"); } Console.ReadLine(); } // ----- STRUCTS ----- // A struct is a user defined type that // contain multiple fields and methods struct Rectangle { public double length; public double width; // You can create a constructor method // that will set the values for fields public Rectangle(double l=1, double w=1) { length = l; width = w; } public double Area() { return length * width; } } } } ---------- Animal.cs ---------- using System; namespace CSharpTutA.cs{ class Animal { // Attributes (fields) that all Animals have // public means can be directly changed // after an object has been created public string name; public string sound; // A constructor sets default values for // fields when an object is created // This is the default constructor if no // parameters are sent public Animal() { name = "No Name"; sound = "No Sound"; numOfAnimals++; } // You can create additonal constructors // but since we are definig defaults you // don't have to public Animal(string name = "No Name") { // This refers to this objects name // instead of the name passed into // the constructor this.name = name; this.sound = "No Sound"; numOfAnimals++; } public Animal(string name = "No Name", string sound = "No Sound") { this.name = name; this.sound = sound; numOfAnimals++; } // Capabilities (methods) that all Animals have public void MakeSound() { Console.WriteLine("{0} says {1}", name, sound); } // static fields and methods belong to the class // A static field has the same value for all // objects of the Animal type static int numOfAnimals = 0; public static int GetNumAnimals() { return numOfAnimals; } }} ---------- ShapeMath.cs ---------- using System; public static class ShapeMath { // This class can only contain static methods // and constant values public static double GetArea(string shape = "", double length1 = 0, double length2 = 0) { if (String.Equals("Rectangle", shape, StringComparison.OrdinalIgnoreCase)) { return length1 * length2; } else if (String.Equals("Triangle", shape, StringComparison.OrdinalIgnoreCase)) { return length1 * (length2 / 2); } else if (String.Equals("Circle", shape, StringComparison.OrdinalIgnoreCase)) { return 3.14159 * Math.Pow(length1, 2); } else { return -1; } } } xxxxxxxxxx// ----- Animal.cs ----- using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; // We cover public, private, protected, constants,// read-only fields, constructors, setters, getters, // properties and more on static namespace CSharpTutA.cs{ class Animal { // Define fields that are protected with private // Private fields can only be accessed by // methods in the class and they are not // accessible by subclasses // protected fields can only be accessed by // methods in the class and by subclasses private string name; private string sound; // You can define constants public const string SHELTER = "Derek's Home for Animals"; // You can define read-only fields that are set // at runtime in constructors, but then can't // be changed public readonly int idNum; // Method (Capabilities) public void MakeSound() { Console.WriteLine("{0} says {1}", name, sound); } // Default constructor public Animal() :this("No Name", "No Sound") { } // Constructor called if only name is passed // this passes the parameters to the next // constructor public Animal(string name) : this(name, "No Sound") { } // Constructor that receives parameters public Animal(string name, string sound) { SetName(name); Sound = sound; // Increment the number of animals // property NumOfAnimals = 1; // Define the read-only value which is // the same for all Animals Random rnd = new Random(); idNum = rnd.Next(1, 2147483640); } // Setters (Mutators) protect the fields // from receiving bad data public void SetName(string name) { // Any checks if any character in the string // is a number and if so returns true // Since we won't allow numbers we will // protect our data if (!name.Any(char.IsDigit)) { this.name = name; } else { // We have this duplicated code because // everything isn't a property this.name = "No Name"; Console.WriteLine("Name can't contain numbers"); } } // Getters (Accessors) can provide output // aside from the value stored public string GetName() { return name; } // The preferred way to define getters and // setters is through properties public string Sound { get { return sound; } set { // value is assigned the value passed in if (value.Length > 10) { sound = "No Sound"; Console.WriteLine("Sound is too long"); } else { sound = value; } } } // You can have the getters and setters // generated for you like this and also // set the default value public string Owner { get; set; } = "No Owner"; // You can also define static properties public static int numOfAnimals = 0; public static int NumOfAnimals { get { return numOfAnimals; } set { numOfAnimals += value; } } }} // ----- Program.cs ----- using System; namespace CSharpTutA.cs{ class Program { static void Main(string[] args) { Animal cat = new Animal(); // Call the setter cat.SetName("Whiskers"); // Set the property cat.Sound = "Meow"; Console.WriteLine("The cat is named {0} and says {1}", cat.GetName(), cat.Sound); // Test auto generated getters and setters cat.Owner = "Derek"; Console.WriteLine("{0} owner is {1}", cat.GetName(), cat.Owner); // Get the read-only id number Console.WriteLine("{0} shelter id is {1}", cat.GetName(), cat.idNum); // Test static property Console.WriteLine("# of Animals : {0}", Animal.NumOfAnimals); Console.ReadLine(); } } } xxxxxxxxxx---------- Animal.cs ---------- using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; namespace CSharpTutA.cs{ // If this class was sealed you couldn't inherit // from it sealed class Animal class Animal { private string name; // A protected field can be changed by // a subclass directly protected string sound; // Inheritance has a "is-a" relationship, // while an aggregation or delegate // represents a "Has-a" relationship // like we have here with the AnimalIDInfo // object protected AnimalIDInfo animalIDInfo = new AnimalIDInfo(); public void SetAnimalIDInfo(int idNum, string owner) { animalIDInfo.IDNum = idNum; animalIDInfo.Owner = owner; } public void GetAnimalIDInfo() { Console.WriteLine($"{Name} has the ID of {animalIDInfo.IDNum} and is owned by {animalIDInfo.Owner}"); } // Added virtual so that this method can // be overridden by subclasses // You must add override to the method in // the subclass public virtual void MakeSound() { Console.WriteLine($"{Name} says {Sound}"); } public Animal() :this("No Name", "No Sound") { } public Animal(string name) :this(name, "No Sound") { } public Animal(string name, string sound) { Name = name; Sound = sound; } public string Name { get { return name; } set { if (!value.Any(char.IsDigit)) { name = "No Name"; } else { name = value; } } } public string Sound { get { return sound; } set { if(value.Length > 10) { sound = "No Sound"; } sound = value; } } // You can create inner classes that are // normally helper classes for the outer // class because it can access private // members of the outer class public class AnimalHealth { public bool HealthyWeight(double height, double weight) { double calc = height / weight; if ((calc >= .18) && (calc <= .27)) { return true; } else return false; } } }} ---------- Dog.cs ---------- using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; namespace CSharpTutA.cs{ // When you inherit from another class you // receive all of its fields and methods // You cannot inherit from multiple classes class Dog : Animal { // You can add additional properties // or fields public string Sound2 { get; set; } = "Grrrrr"; // You can overwrite methods by adding new /* public new void MakeSound() { Console.WriteLine($"{Name} says {Sound} and {Sound2}"); } */ // Add override so that the correct method // is called when a Dog is created as an // Animal type public override void MakeSound() { Console.WriteLine($"{Name} says {Sound} and {Sound2}"); } // Create a constructor that has the base // constructor initialize everything except // Sound2 public Dog(string name = "No Name", string sound = "No Sound", string sound2 = "No Sound 2") :base(name, sound){ Sound2 = sound2; } }} ---------- Program.cs ---------- using System; namespace CSharpTutA.cs{ class Program { static void Main(string[] args) { Animal whiskers = new Animal() { Name = "Whiskers", Sound = "Meow" }; Dog grover = new Dog() { Name = "Grover", Sound = "Woof", Sound2 = "Grrrrr" }; // Demonstrate changing the protected // field sound grover.Sound = "Wooooof"; whiskers.MakeSound(); grover.MakeSound(); // Define the AnimalIDInfo whiskers.SetAnimalIDInfo(12345, "Sally Smith"); grover.SetAnimalIDInfo(12346, "Paul Brown"); whiskers.GetAnimalIDInfo(); // Test the inner class Animal.AnimalHealth getHealth = new Animal.AnimalHealth(); Console.WriteLine("Is my animal healthy : {0}", getHealth.HealthyWeight(11, 46)); // You can define 2 Animal objects but have // one actually be a Dog type. Animal monkey = new Animal() { Name = "Happy", Sound = "Eeeeee" }; Animal spot = new Dog() { Name = "Spot", Sound = "Wooooff", Sound2 = "Geerrrr" }; // The problem is that if you call a // function in Animal it won't call // the overridden method in Dog unless // the method that might be overridden // is marked virtual spot.MakeSound(); // This is an example of how Polymorphism // allows a subclass to override a method // in the super class and even if the // subclass is defined as the super class // type the correct method will be called Console.ReadLine(); } } } ---------- AnimalIDInfo.cs ---------- using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; namespace CSharpTutA.cs{ class AnimalIDInfo { public int IDNum { get; set; } = 0; public string Owner { get; set; } = "No Owner"; }} xxxxxxxxxx// ---------- Warrior.cs ---------- using System; namespace CSharpTutA.cs{ class Warrior { // Define the Warriors properties public string Name { get; set; } = "Warrior"; public double Health { get; set; } = 0; public double AttkMax { get; set; } = 0; public double BlockMax { get; set; } = 0; // Always create a single Random instance and reuse // it or you will get the same value over and over Random rnd = new Random(); // Constructor initializes the warrior public Warrior(string name = "Warrior", double health = 0, double attkMax = 0, double blockMax = 0) { Name = name; Health = health; AttkMax = attkMax; BlockMax = blockMax; } // Generate a random atack value from 1 // to the warriors maximum attack value public double Attack() { return rnd.Next(1, (int)AttkMax); } // Generate a random block value from // 1 to the warriors maximum block public double Block() { return rnd.Next(1, (int)BlockMax); } }} // ---------- Battle.cs ---------- using System; namespace CSharpTutA.cs{ class Battle { // This is a utility class so it makes sense // to have just static methods // Recieve both Warrior objects public static void StartFight(Warrior warrior1, Warrior warrior2) { // Loop giving each Warrior a chance to attack // and block each turn until 1 dies while (true) { if (GetAttackResult(warrior1, warrior2) == "Game Over") { Console.WriteLine("Game Over"); break; } if (GetAttackResult(warrior2, warrior1) == "Game Over") { Console.WriteLine("Game Over"); break; } } } // Accept 2 Warriors public static string GetAttackResult(Warrior warriorA, Warrior warriorB) { // Calculate one Warriors attack and the others block double warAAttkAmt = warriorA.Attack(); double warBBlkAmt = warriorB.Block(); // Subtract block from attack double dmg2WarB = warAAttkAmt - warBBlkAmt; // If there was damage subtract that from the health if (dmg2WarB > 0) { warriorB.Health = warriorB.Health - dmg2WarB; } else dmg2WarB = 0; // Print out info on who attacked who and for how // much damage Console.WriteLine("{0} Attacks {1} and Deals {2} Damage", warriorA.Name, warriorB.Name, dmg2WarB); // Provide output on the change to health Console.WriteLine("{0} Has {1} Health\n", warriorB.Name, warriorB.Health); // Check if the warriors health fell below // zero and if so print a message and send // a response that will end the loop if (warriorB.Health <= 0) { Console.WriteLine("{0} has Died and {1} is Victorious\n", warriorB.Name, warriorA.Name); return "Game Over"; } else return "Fight Again"; } }} // ---------- Program.cs ---------- using System; namespace CSharpTutA.cs{ class Program { /* Bob Attacks Maximus and Deals 74 Damage Maximus Has 69 Health Maximus Attacks Bob and Deals 6 Damage Bob Has 6 Health Bob Attacks Maximus and Deals 48 Damage Maximus Has 21 Health Maximus Attacks Bob and Deals 48 Damage Bob Has -42 Health Bob has Died and Maximus is Victorious Game Over */ static void Main(string[] args) { Warrior maximus = new Warrior("Maximus", 1000, 120, 40); Warrior bob = new Warrior("Bob", 1000, 120, 40); Battle.StartFight(maximus, bob); Console.ReadLine(); } } }
xxxxxxxxxx// ---------- Shape.cs ----------using System; // Very often you want to define a// class that you don't want to be// instantiated. In that case an // Abstract class may be the way to// go. namespace CSharpTutA.cs{ abstract class Shape { public string Name { get; set; } // You can define non-abstract // methods in an abstract class public virtual void GetInfo() { Console.WriteLine($"This is a {Name}"); } // We want subclasses to override // this method so mark it as abstract // You can only make abstract methods // in abstract classes public abstract double Area(); }} // ---------- Circle.cs ---------- using System; namespace CSharpTutA.cs{ class Circle : Shape { public double Radius { get; set; } public Circle(double radius) { Name = "Circle"; Radius = radius; } public override double Area() { return Math.PI * (Math.Pow(Radius, 2.0)); } // You can replace the method using override public override void GetInfo() { // Execute the base version base.GetInfo(); Console.WriteLine($"It has a Radius of {Radius}"); } }} // ---------- Rectangle.cs ---------- using System; namespace CSharpTutA.cs{ class Rectangle : Shape { public double Length { get; set; } public double Width { get; set; } public Rectangle(double length, double width) { Name = "Rectangle"; Length = length; Width = width; } public override double Area() { return Length * Width; } // You can replace the method using override public override void GetInfo() { // Execute the base version base.GetInfo(); Console.WriteLine($"It has a Length of {Length} and Width of {Width}"); } }} // ---------- Program.cs ---------- using System; // This time we cover Abstract Classes, Abstract// Methods, Base Classes, Is, As, Casting and// more about Polymorphism namespace CSharpTutA.cs{ class Program { static void Main(string[] args) { // We can store our shapes in // a Shape array as long as it // contains subclasses of Shape Shape[] shapes = {new Circle(5), new Rectangle(4,5)}; // Cycle through shapes and print // the area foreach(Shape s in shapes) { // Call the overidden method s.GetInfo(); Console.WriteLine("{0} Area : {1:f2}", s.Name, s.Area()); // You can use as to check if an // object is of a specific type Circle testCirc = s as Circle; if(testCirc == null) { Console.WriteLine("This isn't a Circle"); } // You can use is to check the data // type if(s is Circle) { Console.WriteLine("This isn't a Rectangle"); } Console.WriteLine(); } // You can store any class as a base // class and call the subclass methods // even if they don't exist in the base // class by casting object circ1 = new Circle(4); Circle circ2 = (Circle)circ1; Console.WriteLine("The {0} Area is {1:f2}", circ2.Name, circ2.Area()); Console.ReadLine(); } } } xxxxxxxxxx// ---------- IDrivable.cs ---------- namespace CSharpTutA.cs{ // An interface is a class with nothing but // abstract methods. Interfaces are used // to represent a contract an object may // decide to support. // Interfaces commonly have names that // are adjectives because adjectives // modify nouns (Objects). The also // describe abstract things // It is common to prefix your interfaces with // an I interface IDrivable { // Interfaces can have properties int Wheels { get; set; } double Speed { get; set; } // Classes that inherit an interface // must fulfill the contract and // implement every abstract method void Move(); void Stop(); }} // ---------- Vehicle.cs ---------- using System; namespace CSharpTutA.cs{ class Vehicle : IDrivable { // Vehicle properties public string Brand { get; set; } public Vehicle(string brand = "No Brand", int wheels = 0, double speed = 0) { Brand = brand; Wheels = wheels; Speed = speed; } // Properties and methods from // the interface public double Speed {get; set;} public int Wheels {get; set;} public void Move() { Console.WriteLine($"The {Brand} Moves Forward at {Speed} MPH"); } public void Stop() { Console.WriteLine($"The {Brand} Stops"); Speed = 0; } }} // ---------- Program.cs ---------- using System; // A class can support multiple interfaces. // Create an interface Project -> Add New Item// and select Interface namespace CSharpTutA.cs{ class Program { static void Main(string[] args) { // Create a Vehicle object Vehicle buick = new Vehicle("Buick", 4, 160); // Check if Vehicle implements // IDrivable if(buick is IDrivable) { buick.Move(); buick.Stop(); } else { Console.WriteLine("The {0} can't be driven", buick.Brand); } // We are now modeling the act of // picking up a remote, aiming it // at the TV, clicking the power // button and then watching as // the TV turns on and off // Pick up the TV remote IElectronicDevice TV = TVRemote.GetDevice(); // Create the power button PowerButton powBut = new PowerButton(TV); // Turn the TV on and off with each // press powBut.Execute(); powBut.Undo(); Console.ReadLine(); } } } // ---------- IElectronicDevice.cs ---------- namespace CSharpTutA.cs{ // With interfaces you can create very // flexible systems. Here I'll model // generic electronic devices like // TVs and Radios and remotes that // control them and the buttons on the // remotes. interface IElectronicDevice { // We want each device to have // these capabilities void On(); void Off(); void VolumeUp(); void VolumeDown(); }} // ---------- Television.cs ---------- using System; namespace CSharpTutA.cs{ // Because we implemented the // ElectronicDevice interface any // other device we create will know // exactly how to interface with it. class Television : IElectronicDevice { public int Volume { get; set; } public void Off() { Console.WriteLine("The TV is Off"); } public void On() { Console.WriteLine("The TV is On"); } public void VolumeDown() { if (Volume != 0) Volume--; Console.WriteLine($"The TV Volume is at {Volume}"); } public void VolumeUp() { if (Volume != 100) Volume++; Console.WriteLine($"The TV Volume is at {Volume}"); } }} // ---------- ICommand.cs ---------- namespace CSharpTutA.cs{ interface ICommand { // We can model what happens when // a button is pressed for example // a power button. By breaking // everything down we can add // an infinite amount of flexibility void Execute(); void Undo(); }} // ---------- PowerButton.cs ---------- namespace CSharpTutA.cs{ class PowerButton : ICommand { // You can refer to instances using // the interface IElectronicDevice device; // Now we get into the specifics of // what happens when the power button // is pressed. public PowerButton(IElectronicDevice device) { this.device = device; } public void Execute() { device.On(); } // You can provide a way to undo // an action just like the power // button does on a remote public void Undo() { device.Off(); } }} // ---------- TVRemote.cs ---------- namespace CSharpTutA.cs{ class TVRemote { // Now we are modeling the action of // picking up the remote with our hand public static IElectronicDevice GetDevice() { return new Television(); } }} xxxxxxxxxxusing System;using System.Linq; // Used for ArrayListsusing System.Collections; // Used for Dictionaryusing System.Collections.Generic; namespace CSharpTutA.cs{ class Program { static void Main(string[] args) { // Collections can resize unlike arrays // #region provides a way to collapse // long blocks of code // ---------- ARRAYLISTS ---------- // ArrayLists are resizable arrays // that can hold multiple data types ArrayList aList = new ArrayList(); aList.Add("Bob"); aList.Add(40); // Number of items in list Console.WriteLine("Count: {0}", aList.Count); // The capacity automatically increases // as items are added Console.WriteLine("Capacity: {0}", aList.Capacity); ArrayList aList2 = new ArrayList(); // Add an object array aList2.AddRange(new object[] { "Mike", "Sally", "Egg" }); // Add 1 array list to another aList.AddRange(aList2); // You can sort the list if the types // are the same aList2.Sort(); aList2.Reverse(); // Insert at the 2nd position aList2.Insert(1, "Turkey"); // Get the 1st 2 items ArrayList range = aList2.GetRange(0, 2); /* // Remove the first item aList2.RemoveAt(0); // Remove the 1st 2 items aList2.RemoveRange(0, 2); */ // Search for a match starting at the provided // index. You can also find the last index // with LastIndexOf Console.WriteLine("Turkey Index : {0}", aList2.IndexOf("Turkey", 0)); // Cycle through the list foreach (object o in range) { Console.WriteLine(o); } // Convert an ArrayList into a string array string[] myArray = (string[])aList2.ToArray(typeof(string)); // Convert a string array into an ArrayList string[] customers = { "Bob", "Sally", "Sue" }; ArrayList custArrayList = new ArrayList(); custArrayList.AddRange(customers); #endregion // ---------- DICTIONARIES ---------- #region Dictionary Code // Dictionaries store key value pairs // To create them define the data // type for the key and the value Dictionary<string, string> superheroes = new Dictionary<string, string>(); superheroes.Add("Clark Kent", "Superman"); superheroes.Add("Bruce Wayne", "Batman"); superheroes.Add("Barry West", "Flash"); // Remove a key / value superheroes.Remove("Barry West"); // Number of keys Console.WriteLine("Count : {0}", superheroes.Count); // Check if a key is present Console.WriteLine("Clark Kent : {0}", superheroes.ContainsKey("Clark Kent")); // Get the value for the key and store it // in a string superheroes.TryGetValue("Clark Kent", out string test); Console.WriteLine($"Clark Kent : {test}"); // Cycle through key value pairs foreach(KeyValuePair<string, string> item in superheroes) { Console.WriteLine("{0} : {1}", item.Key, item.Value); } // Clear a dictionary superheroes.Clear(); #endregion // ---------- QUEUES ---------- #region Queue Code // Queue 1st in 1st Out Collection // Create a Queue Queue queue = new Queue(); // Add values queue.Enqueue(1); queue.Enqueue(2); queue.Enqueue(3); // Is item in queue Console.WriteLine("1 in Queue : {0}", queue.Contains(1)); // Remove 1st item from queue Console.WriteLine("Remove 1 : {0}", queue.Dequeue()); // Look at 1st item but don't remove Console.WriteLine("Peek 1 : {0}", queue.Peek()); // Copy queue to array object[] numArray = queue.ToArray(); // Print array Console.WriteLine(string.Join(",", numArray)); // Print queue items foreach (object o in queue) { Console.WriteLine($"Queue : {o}"); } // Clear the queue queue.Clear(); #endregion // ---------- STACKS ---------- #region Queue Code // Stack Last in 1st Out Collection // Create a stack Stack stack = new Stack(); // Put items on the stack stack.Push(1); stack.Push(2); stack.Push(3); // Get but don't remove item Console.WriteLine("Peek 1 : {0}", stack.Peek()); // Remove item Console.WriteLine("Pop 1 : {0}", stack.Pop()); // Does item exist on stack Console.WriteLine("Contain 1 : {0}", stack.Contains(1)); // Copy stack to array object[] numArray2 = stack.ToArray(); // Print array Console.WriteLine(string.Join(",", numArray2)); // Print the stack foreach (object o in stack) { Console.WriteLine($"Stack : {o}"); } // Clear stack Console.ReadLine(); } } } xxxxxxxxxx// ---------- Animal.cs ---------- using System; namespace CSharpTutA.cs{ class Animal { public string Name { get; set; } public Animal(string name = "No Name") { Name = name; } // Anytime you need many overloaded // methods that differ only by their // parameters a generic is normally // the solution public static void GetSum<T>(ref T num1, ref T num2) { double dblX = Convert.ToDouble(num1); double dblY = Convert.ToDouble(num2); Console.WriteLine($"{dblX} + {dblY} = {dblX + dblY}"); } }} // ---------- Program.cs ---------- using System;using System.Linq;using System.Collections.Generic; namespace CSharpTutA.cs{ class Program { static void Main(string[] args) { // Generic collections are type safe // and provide performance benefits // You define the data type when defining // the generic. This is a dynamically // resizing collection List<Animal> animalList = new List<Animal>(); // You can also create a list of standard // types like int List<int> numList = new List<int>(); // Add an int numList.Add(24); // Add Animals animalList.Add(new Animal() { Name = "Doug" }); animalList.Add(new Animal() { Name = "Paul" }); animalList.Add(new Animal() { Name = "Sally" }); // Insert in index 1 animalList.Insert(1, new Animal() { Name = "Steve" }); // Remove index 1 animalList.RemoveAt(1); // Get number of Animals Console.WriteLine("Num of Animals : {0}", animalList.Count()); // Cycle through Animals foreach(Animal a in animalList) { Console.WriteLine(a.Name); } // You can also use Stack<T>, Queue<T>, // Dictionary<TKey, TValue> like I covered // previously // Generic methods // You can use the type parameter <int> // if it can be inferred from the parameters // passed (Can't do this if there are no // parameters int x = 5, y = 4; Animal.GetSum<int>(ref x, ref y); // It works for strings as well string strX = "5", strY = "4"; Animal.GetSum(ref strX, ref strY); // Use the generic struct Rectangle<int> rec1 = new Rectangle<int>(20, 50); Console.WriteLine(rec1.GetArea()); Rectangle<string> rec2 = new Rectangle<string>("20", "50"); Console.WriteLine(rec2.GetArea()); // Delegates allow you to reference methods // inside a delegate object. The delegate // object can then be passed to other // methods that can call the methods assigned // to the delegate. It can also stack methods // that are called in the specified order // Create delegate objects Arithmetic add, sub, addSub; // Assign just the Add method add = new Arithmetic(Add); // Assign just the Subtract method sub = new Arithmetic(Subtract); // Assign Add and Sub addSub = add + sub; // You could also subtract a method // sub = addSub - add; // Print out results Console.WriteLine($"Add {6} & {10}"); add(6, 10); // Call both methods Console.WriteLine($"Add & Subtract {10} & {4}"); addSub(10, 4); Console.ReadLine(); } // You can also create generic structs // and classes in this same way public struct Rectangle<T> { // Generic fields private T width; private T length; // Generic properties public T Width { get { return width; } set { width = value; } } public T Length { get { return length; } set { length = value; } } // Generic constructor public Rectangle(T w, T l) { width = w; length = l; } public string GetArea() { double dblWidth = Convert.ToDouble(Width); double dblLength = Convert.ToDouble(Length); return string.Format($"{Width} * {Length} = {dblWidth * dblLength}"); } } // Declare a delegate type that performs // arithmetic. It defines the return type // and the types for attributes public delegate void Arithmetic(double num1, double num2); // Methods that will be assigned to the delegate public static void Add(double num1, double num2) { Console.WriteLine($"{num1} + {num2} = {num1 + num2}"); } public static void Subtract(double num1, double num2) { Console.WriteLine($"{num1} - {num2} = {num1 - num2}"); } } } using System;using System.Linq;using System.Collections.Generic; namespace CSharpTutA.cs{ // This time I'll cover multiple functions // you can use to work with lists of data // including Lambda, Where, ToList, Select, // Zip, Aggregate and Average class Program { // Delegate that is assigned a Lambda // expression delegate double doubleIt(double val); static void Main(string[] args) { // Like we did with predicates earlier // Lambda expressions allow you to // use anonymous methods that define // the input parameters on the left // and the code to execute on the right // Assign a Lambda to the delegate doubleIt dblIt = x => x * 2; Console.WriteLine($"5 * 2 = {dblIt(5)}"); // You don't have to use delegates though // Here we'll search through a list to // find all the even numbers List<int> numList = new List<int> { 1,9,2,6,3 }; // Put the number in the list if the // condition is true var evenList = numList.Where(a => a % 2 == 0).ToList(); foreach (var j in evenList) Console.WriteLine(j); // Add values in a range to a list var rangeList = numList.Where(x => (x > 2) || (x < 9)).ToList(); foreach (var k in rangeList) Console.WriteLine(k); // Find the number of heads and tails in // a list 1 = H, 2 = T // Generate our list List<int> flipList = new List<int>(); int i = 0; Random rnd = new Random(); while (i < 100) { flipList.Add(rnd.Next(1, 3)); i++; } // Print out the heads and tails Console.WriteLine("Heads : {0}", flipList.Where(a => a == 1).ToList().Count()); // Same as flipList.Count (a ==> a== 1) Console.WriteLine("Tails : {0}", flipList.Where(a => a == 2).ToList().Count()); // Same as flipList.Count (a ==> a== 2) // Find all names starting with s var nameList = new List<string> { "Doug", "Sally", "Sue" }; var sNameList = nameList.Where(x => x.StartsWith("S")); foreach (var m in sNameList) Console.WriteLine(m); // ---------- SELECT ---------- // Select allows us to execute a function // on each item in a list // Generate a list from 1 to 10 var oneTo10 = new List<int>(); oneTo10.AddRange(Enumerable.Range(1, 10)); var squares = oneTo10.Select(x => x * x); foreach (var l in squares) Console.WriteLine(l); // ---------- ZIP ---------- // Zip applies a function to two lists // Add values in 2 lists together var listOne = new List<int>(new int[] { 1, 3, 4}); var listTwo = new List<int>(new int[] { 4, 6, 8}); var sumList = listOne.Zip(listTwo, (x, y) => x + y).ToList(); foreach (var n in sumList) Console.WriteLine(n); // ---------- AGGREGATE ---------- // Aggregate performs an operation on // each item in a list and carries the // results forward // Sum values in a list var numList2 = new List<int>() { 1, 2, 3, 4, 5 }; Console.WriteLine("Sum : {0}", numList2.Aggregate((a, b) => a + b)); // ---------- AVERAGE ---------- // Get the average of a list of values var numList3 = new List<int>() { 1, 2, 3, 4, 5 }; // AsQueryable allows you to manipulate the // collection with the Average function Console.WriteLine("AVG : {0}", numList3.AsQueryable().Average()); // ---------- ALL ---------- // Determines if all items in a list // meet a condition var numList4 = new List<int>() { 1, 2, 3, 4, 5 }; Console.WriteLine("All > 3 : {0}", numList4.All(x => x > 3)); // ---------- ANY ---------- // Determines if any items in a list // meet a condition var numList5 = new List<int>() { 1, 2, 3, 4, 5 }; Console.WriteLine("Any > 3 : {0}", numList5.Any(x => x > 3)); // ---------- DISTINCT ---------- // Eliminates duplicates from a list var numList6 = new List<int>() { 1, 2, 3, 2, 3 }; Console.WriteLine("Distinct : {0}", string.Join(", ", numList6.Distinct())); // ---------- EXCEPT ---------- // Receives 2 lists and returns values not // found in the 2nd list var numList7 = new List<int>() { 1, 2, 3, 2, 3 }; var numList8 = new List<int>() { 3 }; Console.WriteLine("Except : {0}", string.Join(", ", numList7.Except(numList8))); // ---------- INTERSECT ---------- // Receives 2 lists and returns values that // both lists have var numList9 = new List<int>() { 1, 2, 3, 2, 3 }; var numList10 = new List<int>() { 2, 3 }; Console.WriteLine("Intersect : {0}", string.Join(", ", numList9.Intersect(numList10))); Console.ReadLine(); } } } xxxxxxxxxx// ---------- Animal.cs ---------- namespace CSharpTutA.cs{ class Animal { public string Name { get; set; } public Animal(string name = "No Name") { Name = name; } }} // ---------- AnimalFarm.cs ---------- using System.Collections;using System.Collections.Generic; namespace CSharpTutA.cs{ // IEnumerable provides for iteration // over a collection class AnimalFarm : IEnumerable { // Holds list of Animals private List<Animal> animalList = new List<Animal>(); public AnimalFarm(List<Animal> animalList) { this.animalList = animalList; } public AnimalFarm() { } // Indexer for AnimalFarm created with this[] public Animal this[int index] { get { return (Animal)animalList[index]; } set { animalList.Insert(index, value); } } // Returns the number of values in the // collection public int Count { get{ return animalList.Count; } } // Returns an enumerator that is used to // iterate through the collection IEnumerator IEnumerable.GetEnumerator() { return animalList.GetEnumerator(); } }} // ---------- Box.cs ---------- using System; namespace CSharpTutA.cs{ class Box { public double Length { get; set; } public double Width { get; set; } public double Breadth { get; set; } public Box() :this(1,1,1) { } public Box(double l, double w, double b) { Length = l; Width = w; Breadth = b; } public static Box operator +(Box box1, Box box2) { Box newBox = new Box() { Length = box1.Length + box2.Length, Width = box1.Width + box2.Width, Breadth = box1.Breadth + box2.Breadth }; return newBox; } // Through operator overloading you can // allow users to interact with your // custom objects in interesting ways // You can overload +, -, *, /, %, !, // ==, !=, >, <, >=, <=, ++ and -- public static Box operator -(Box box1, Box box2) { Box newBox = new Box() { Length = box1.Length - box2.Length, Width = box1.Width - box2.Width, Breadth = box1.Breadth - box2.Breadth }; return newBox; } public static bool operator ==(Box box1, Box box2) { if((box1.Length == box2.Length) && (box1.Width == box2.Width) && (box1.Breadth == box2.Breadth)) { return true; } return false; } public static bool operator !=(Box box1, Box box2) { if ((box1.Length != box2.Length) || (box1.Width != box2.Width) || (box1.Breadth != box2.Breadth)) { return true; } return false; } // You define how your object is converted // into a string by overridding ToString public override string ToString() { return String.Format("Box with Height : {0} Width : {1} and Breadth : {2}", Length, Width, Breadth); } // You can convert from a Box into an // int like this even though this // wouldn't make sense public static explicit operator int(Box b) { return (int)(b.Length + b.Width + b.Breadth) / 3; } // Convert from an int to a Box public static implicit operator Box(int i) { // Return a box with the lengths all // set to the int passed return new Box(i, i, i); } }} // ---------- Program.cs ---------- using System;using System.Linq;using System.Collections.Generic; namespace CSharpTutA.cs{ // Indexers allow you to access items // like arrays class Program { static void Main(string[] args) { // Create an AnimalFarm object AnimalFarm myAnimals = new AnimalFarm(); // Add Animals myAnimals[0] = new Animal("Wilbur"); myAnimals[1] = new Animal("Templeton"); myAnimals[2] = new Animal("Gander"); myAnimals[3] = new Animal("Charlotte"); foreach(Animal i in myAnimals) { Console.WriteLine(i.Name); } // Testing operator overloading Box box1 = new Box(2, 3, 4); Box box2 = new Box(5,6,7); Box box3 = box1 + box2; // Converts the box to a string with // ToString Console.WriteLine($"Box 3 : {box3}"); Console.WriteLine($"Box Int : {(int)box3}"); // Convert an int into a Box Box box4 = (Box)4; Console.WriteLine($"Box 4 : {(Box)4}"); // Sometimes you want to build a simple // class that contains fields and // Anonymous types are great for that var shopkins = new { Name = "Shopkins", Price = 4.99 }; Console.WriteLine("{0} cost ${1}", shopkins.Name, shopkins.Price); // Anonymous types can also be stored // in an array var toyArray = new[] { new { Name = "Yo-Kai Pack", Price = 4.99 }, new { Name = "Legos", Price = 9.99 } }; // You can loop through the array foreach(var item in toyArray) { Console.WriteLine("{0} costs ${1}", item.Name, item.Price); } Console.WriteLine(); Console.ReadLine(); } } } xxxxxxxxxx// ---------- Animal.cs ---------- namespace CSharpTutA.cs{ class Animal { public string Name { get; set; } public double Weight { get; set; } public double Height { get; set; } public int AnimalID { get; set; } public Animal(string name = "No Name", double weight = 0, double height = 0) { Name = name; Weight = weight; Height = height; } public override string ToString() { return string.Format("{0} weighs {1}lbs and is {2} inches tall", Name, Weight, Height); } }} // ---------- Owner.cs ---------- namespace CSharpTutA.cs{ class Owner { public string Name { get; set; } public int OwnerID { get; set; } }} // ---------- Program.cs ---------- using System;using System.Linq;using System.Collections;using System.Collections.Generic; namespace CSharpTutA.cs{ // Language Integrated Query (LINQ) provides // many tools for working with data // LINQ is similar to SQL, but it can work // with data aside from databases // You manipulate data using Query Expressions class Program { static void Main(string[] args) { QueryStringArray(); // Get the array returned and print it int[] intArray = QueryIntArray(); foreach(int i in intArray) Console.WriteLine(i); Console.WriteLine(); QueryArrayList(); QueryCollection(); QueryAnimalData(); Console.ReadLine(); } static void QueryStringArray() { string[] dogs = {"K 9", "Brian Griffin", "Scooby Doo", "Old Yeller", "Rin Tin Tin", "Benji", "Charlie B. Barkin", "Lassie", "Snoopy"}; // Get strings with spaces and put in // alphabetical order // from states where data comes from and // where to store each piece as you cycle // where defines conditions that must be met // orderby defines what data is used for // ordering results (ascending / descending) // select defines the variable that is // checked against the condition var dogSpaces = from dog in dogs where dog.Contains(" ") orderby dog descending select dog; foreach(var i in dogSpaces) { Console.WriteLine(i); } Console.WriteLine(); } static int[] QueryIntArray() { int[] nums = { 5, 10, 15, 20, 25, 30, 35 }; // Get numbers bigger then 20 var gt20 = from num in nums where num > 20 orderby num select num; foreach(var i in gt20) { Console.WriteLine(i); } Console.WriteLine(); // The type is an enumerable Console.WriteLine($"Get Type : {gt20.GetType()}"); // You can convert it into a List or array var listGT20 = gt20.ToList<int>(); var arrayGT20 = gt20.ToArray(); // If you change the data the query // automatically updates nums[0] = 40; foreach (var i in gt20) { Console.WriteLine(i); } Console.WriteLine(); return arrayGT20; } static void QueryArrayList() { ArrayList famAnimals = new ArrayList() { new Animal{Name = "Heidi", Height = .8, Weight = 18}, new Animal { Name = "Shrek", Height = 4, Weight = 130 }, new Animal { Name = "Congo", Height = 3.8, Weight = 90 } }; // You have to convert the ArrayList into // an IEnumerable var famAnimalEnum = famAnimals.OfType<Animal>(); var smAnimals = from animal in famAnimalEnum where animal.Weight <= 90 orderby animal.Name select animal; foreach(var animal in smAnimals) { Console.WriteLine("{0} weighs {1}lbs", animal.Name, animal.Weight); } Console.WriteLine(); } static void QueryCollection() { var animalList = new List<Animal>() { new Animal{Name = "German Shepherd", Height = 25, Weight = 77}, new Animal{Name = "Chihuahua", Height = 7, Weight = 4.4}, new Animal{Name = "Saint Bernard", Height = 30, Weight = 200} }; var bigDogs = from dog in animalList where (dog.Weight > 70) && (dog.Height > 25) orderby dog.Name select dog; foreach(var dog in bigDogs) { Console.WriteLine("A {0} weighs {1}lbs", dog.Name, dog.Weight); } Console.WriteLine(); } static void QueryAnimalData() { Animal[] animals = new[] { new Animal{Name = "German Shepherd", Height = 25, Weight = 77, AnimalID = 1}, new Animal{Name = "Chihuahua", Height = 7, Weight = 4.4, AnimalID = 2}, new Animal{Name = "Saint Bernard", Height = 30, Weight = 200, AnimalID = 3}, new Animal{Name = "Pug", Height = 12, Weight = 16, AnimalID = 1}, new Animal{Name = "Beagle", Height = 15, Weight = 23, AnimalID = 2} }; Owner[] owners = new[] { new Owner{Name = "Doug Parks", OwnerID = 1}, new Owner{Name = "Sally Smith", OwnerID = 2}, new Owner{Name = "Paul Brooks", OwnerID = 3} }; // Remove name and height var nameHeight = from a in animals select new { a.Name, a.Height }; // Convert to an object array Array arrNameHeight = nameHeight.ToArray(); foreach (var i in arrNameHeight) { Console.WriteLine(i.ToString()); } Console.WriteLine(); // Create an inner join // Join info in owners and animals using // equal values for IDs // Store values for animal and owner var innerJoin = from animal in animals join owner in owners on animal.AnimalID equals owner.OwnerID select new { OwnerName = owner.Name, AnimalName = animal.Name }; foreach (var i in innerJoin) { Console.WriteLine("{0} owns {1}", i.OwnerName, i.AnimalName); } Console.WriteLine(); // Create a group inner join // Get all animals and put them in a // newly created owner group if their // IDs match the owners ID var groupJoin = from owner in owners orderby owner.OwnerID join animal in animals on owner.OwnerID equals animal.AnimalID into ownerGroup select new { Owner = owner.Name, Animals = from owner2 in ownerGroup orderby owner2.Name select owner2 }; int totalAnimals = 0; foreach (var ownerGroup in groupJoin) { Console.WriteLine(ownerGroup.Owner); foreach (var animal in ownerGroup.Animals) { totalAnimals++; Console.WriteLine("* {0}", animal.Name); } } } } } xxxxxxxxxxusing System;using System.Linq;using System.Collections;using System.Collections.Generic;using System.Threading; namespace CSharpTutA.cs{ // With threads you can execute multiple // pieces of code that share resources // and data without corrupting it // You can't guarantee when a thread // executes. You also must lock resources // until a thread is done with them // or you could corrupt them class Program { // ----- Simple Thread Example ----- static void Main(string[] args) { // Create a thread and start it Thread t = new Thread(Print1); t.Start(); // This code will run randomly for (int i = 0; i < 1000; i++) Console.Write(0); Console.ReadLine(); } static void Print1() { for (int i = 0; i < 1000; i++) Console.Write(1); } // ----- Sleep Example ----- // With sleep() the thread is suspended // for the designated amount of time static void Main(string[] args) { int num = 1; for (int i = 0; i < 10; i++) { Console.WriteLine(num); // Pause for 1 second Thread.Sleep(1000); num++; } Console.WriteLine("Thread Ends"); Console.ReadLine(); } // ----- Lock Example ----- // lock keeps other threads from entering // a statement block until another thread // leaves static void Main(string[] args) { BankAcct acct = new BankAcct(10); Thread[] threads = new Thread[15]; // CurrentThread gets you the current // executing thread Thread.CurrentThread.Name = "main"; // Create 15 threads that will call for // IssueWithdraw to execute for (int i = 0; i < 15; i++) { // You can only point at methods // without arguments and that return // nothing Thread t = new Thread(new ThreadStart(acct.IssueWithdraw)); t.Name = i.ToString(); threads[i] = t; } // Have threads try to execute for (int i = 0; i < 15; i++) { // Check if thread has started Console.WriteLine("Thread {0} Alive : {1}", threads[i].Name, threads[i].IsAlive); // Start thread threads[i].Start(); // Check if thread has started Console.WriteLine("Thread {0} Alive : {1}", threads[i].Name, threads[i].IsAlive); } // Get thread priority (Normal Default) // Also Lowest, BelowNormal, AboveNormal // and Highest // Changin priority doesn't guarantee // the highest precedence though // It is best to not mess with this Console.WriteLine("Current Priority : {0}", Thread.CurrentThread.Priority); Console.WriteLine("Thread {0} Ending", Thread.CurrentThread.Name); Console.ReadLine(); } }} class BankAcct{ private Object acctLock = new Object(); double Balance { get; set; } string Name { get; set; } public BankAcct(double bal) { Balance = bal; } public double Withdraw(double amt) { if((Balance - amt) < 0) { Console.WriteLine($"Sorry ${Balance} in Account"); return Balance; } lock (acctLock) { if(Balance >= amt) { Console.WriteLine("Removed {0} and {1} left in Account", amt, (Balance - amt)); Balance -= amt; } return Balance; } } // You can only point at methods // without arguments and that return // nothing public void IssueWithdraw() { Withdraw(1); }} // ----- Passing Data to Threads ----- // You can pass arguments to a thread // using a lambda expression static void Main(string[] args) { Thread t = new Thread(() => CountTo(10)); t.Start(); // You can use multiline lambdas new Thread(() => { CountTo(5); CountTo(6); }).Start(); Console.ReadLine(); } static void CountTo(int maxNum) { for(int i = 0; i <= maxNum; i++) { Console.WriteLine(i); } } }} xxxxxxxxxxusing System;using System.Linq;using System.Collections;using System.Collections.Generic; // Used for file and directory// manipulationusing System.IO;using System.Text; // Start VS with admin rights by// right clicking it and run as // administrator namespace CSharpTutA.cs{ class Program { static void Main(string[] args) { // ----- MESSING WITH DIRECTORIES ----- // Get access to the current directory DirectoryInfo currDir = new DirectoryInfo("."); // Get access to a directory with a path DirectoryInfo dereksDir = new DirectoryInfo(@"C:\Users\derekbanas"); // Get the directory path Console.WriteLine(dereksDir.FullName); // Get the directory name Console.WriteLine(dereksDir.Name); // Get the parent directory Console.WriteLine(dereksDir.Parent); // What type is it Console.WriteLine(dereksDir.Attributes); // When was it created Console.WriteLine(dereksDir.CreationTime); // Create a directory DirectoryInfo dataDir = new DirectoryInfo(@"C:\Users\derekbanas\C#Data"); dataDir.Create(); // Delete a directory // Directory.Delete(@"C:\Users\derekbanas\C#Data"); // ----- SIMPLE FILE READING & WRITING ----- // Write a string array to a text file string[] customers = { "Bob Smith", "Sally Smith", "Robert Smith" }; string textFilePath = @"C:\Users\derekbanas\C#Data\testfile1.txt"; ; // Write the array File.WriteAllLines(textFilePath, customers); // Read strings from array foreach (string cust in File.ReadAllLines(textFilePath)) { Console.WriteLine($"Customer : {cust}"); } // ----- GETTING FILE DATA ----- DirectoryInfo myDataDir = new DirectoryInfo(@"C:\Users\derekbanas\C#Data"); // Get all txt files FileInfo[] txtFiles = myDataDir.GetFiles("*.txt", SearchOption.AllDirectories); // Number of matches Console.WriteLine("Matches : {0}", txtFiles.Length); foreach (FileInfo file in txtFiles) { // Get file name Console.WriteLine(file.Name); // Get bytes in file Console.WriteLine(file.Length); } // ----- FILESTREAMS ----- // FileStream is used to read and write a byte // or an array of bytes. string textFilePath2 = @"C:\Users\derekbanas\C#Data\testfile2.txt"; // Create and open a file FileStream fs = File.Open(textFilePath2, FileMode.Create); string randString = "This is a random string"; // Convert to a byte array byte[] rsByteArray = Encoding.Default.GetBytes(randString); // Write to file by defining the byte array, // the index to start writing from and length fs.Write(rsByteArray, 0, rsByteArray.Length); // Move back to the beginning of the file fs.Position = 0; // Create byte array to hold file data byte[] fileByteArray = new byte[rsByteArray.Length]; // Put bytes in array for(int i = 0; i < rsByteArray.Length; i++) { fileByteArray[i] = (byte)fs.ReadByte(); } // Convert from bytes to string and output Console.WriteLine(Encoding.Default.GetString(fileByteArray)); // Close the FileStream fs.Close(); // ----- STREAMWRITER / STREAMREADER ----- // These are best for reading and writing strings string textFilePath3 = @"C:\Users\derekbanas\C#Data\testfile3.txt"; // Create a text file StreamWriter sw = File.CreateText(textFilePath3); // Write to a file without a newline sw.Write("This is a random "); // Write to a file with a newline sw.WriteLine("sentence."); // Write another sw.WriteLine("This is another sentence."); // Close the StreamWriter sw.Close(); // Open the file for reading StreamReader sr = File.OpenText(textFilePath3); // Peek returns the next character as a unicode // number. Use Convert to change to a character Console.WriteLine("Peek : {0}", Convert.ToChar(sr.Peek())); // Read to a newline Console.WriteLine("1st String : {0}", sr.ReadLine()); // Read to the end of the file starting // where you left off reading Console.WriteLine("Everything : {0}", sr.ReadToEnd()); sr.Close(); // ----- BINARYWRITER / BINARYREADER ----- // Used to read and write data types string textFilePath4 = @"C:\Users\derekbanas\C#Data\testfile4.dat"; // Get the file FileInfo datFile = new FileInfo(textFilePath4); // Open the file BinaryWriter bw = new BinaryWriter(datFile.OpenWrite()); // Data to save to the file string randText = "Random Text"; int myAge = 42; double height = 6.25; // Write data to a file bw.Write(randText); bw.Write(myAge); bw.Write(height); bw.Close(); // Open file for reading BinaryReader br = new BinaryReader(datFile.OpenRead()); // Output data Console.WriteLine(br.ReadString()); Console.WriteLine(br.ReadInt32()); Console.WriteLine(br.ReadDouble()); br.Close(); Console.ReadLine(); } }} xxxxxxxxxx// ---------- Animal.cs ---------- using System;using System.Runtime.Serialization;using System.Runtime.Serialization.Formatters.Binary; // With serialization you can store the state // of an object in a file stream, pass it to// a remote network namespace CSharpTutA.cs{ // Defines that you want to serialize this class [Serializable()] public class Animal : ISerializable { public string Name { get; set; } public double Weight { get; set; } public double Height { get; set; } public int AnimalID { get; set; } public Animal() { } public Animal(string name = "No Name", double weight = 0, double height = 0) { Name = name; Weight = weight; Height = height; } public override string ToString() { return string.Format("{0} weighs {1} lbs and is {2} inches tall", Name, Weight, Height); } // Serialization function (Stores Object Data in File) // SerializationInfo holds the key value pairs // StreamingContext can hold additional info // but we aren't using it here public void GetObjectData(SerializationInfo info, StreamingContext context) { // Assign key value pair for your data info.AddValue("Name", Name); info.AddValue("Weight", Weight); info.AddValue("Height", Height); info.AddValue("AnimalID", AnimalID); } // The deserialize function (Removes Object Data from File) public Animal(SerializationInfo info, StreamingContext ctxt) { //Get the values from info and assign them to the properties Name = (string)info.GetValue("Name", typeof(string)); Weight = (double)info.GetValue("Weight", typeof(double)); Height = (double)info.GetValue("Height", typeof(double)); AnimalID = (int)info.GetValue("AnimalID", typeof(int)); } }} // ---------- Program.cs ---------- using System;using System.Linq;using System.Collections;using System.Collections.Generic; // Used for writing to a fileusing System.IO; // Used to serialize an object to binary formatusing System.Runtime.Serialization.Formatters.Binary; // Used to serialize into XMLusing System.Xml.Serialization; namespace CSharpTutA.cs{ class Program { static void Main(string[] args) { Animal bowser = new Animal("Bowser", 45, 25); // Serialize the object data to a file Stream stream = File.Open("AnimalData.dat", FileMode.Create); BinaryFormatter bf = new BinaryFormatter(); // Send the object data to the file bf.Serialize(stream, bowser); stream.Close(); // Delete the bowser data bowser = null; // Read object data from the file stream = File.Open("AnimalData.dat", FileMode.Open); bf = new BinaryFormatter(); bowser = (Animal)bf.Deserialize(stream); stream.Close(); Console.WriteLine(bowser.ToString()); // Change bowser to show changes were made bowser.Weight = 50; // XmlSerializer writes object data as XML XmlSerializer serializer = new XmlSerializer(typeof(Animal)); using (TextWriter tw = new StreamWriter(@"C:\Users\derekbanas\C#Data\bowser.xml")) { serializer.Serialize(tw, bowser); } // Delete bowser data bowser = null; // Deserialize from XML to the object XmlSerializer deserializer = new XmlSerializer(typeof(Animal)); TextReader reader = new StreamReader(@"C:\Users\derekbanas\C#Data\bowser.xml"); object obj = deserializer.Deserialize(reader); bowser = (Animal)obj; reader.Close(); Console.WriteLine(bowser.ToString()); // Save a collection of Animals List<Animal> theAnimals = new List<Animal> { new Animal("Mario", 60, 30), new Animal("Luigi", 55, 24), new Animal("Peach", 40, 20) }; using (Stream fs = new FileStream(@"C:\Users\derekbanas\C#Data\animals.xml", FileMode.Create, FileAccess.Write, FileShare.None)) { XmlSerializer serializer2 = new XmlSerializer(typeof(List<Animal>)); serializer2.Serialize(fs, theAnimals); } // Delete list data theAnimals = null; // Read data from XML XmlSerializer serializer3 = new XmlSerializer(typeof(List<Animal>)); using (FileStream fs2 = File.OpenRead(@"C:\Users\derekbanas\C#Data\animals.xml")) { theAnimals = (List<Animal>)serializer3.Deserialize(fs2); } foreach (Animal a in theAnimals) { Console.WriteLine(a.ToString()); } Console.ReadLine(); } }} xxxxxxxxxx// ---------- WpfTutorial ---------- // ---------- MainWindow.xaml.cs ---------- using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;using Microsoft.Win32; // Windows Presentation Foundation (WPF)// is used to create graphical user interfaces// of a traditional format or within a// browser (XAML Browser Based App / XBAP) // Using XAML eXtensible Application Markup Language// you can create the UI using XML// XAML allows you to define buttons, boxes,// animations, 2d / 3d graphics and more // Create a New Project -> Visual C# -> Windows// Classic Desktop -> WPF App namespace WpfTut{ /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { string usersName = ""; public MainWindow() { // Initializes and displays the window InitializeComponent(); // You can set window properties in code this.Title = "Hello World"; this.WindowStartupLocation = WindowStartupLocation.CenterScreen; } // When the button is clicked it closes the window private void Button1Clicked(object sender, RoutedEventArgs e) { // Opens a message box MessageBox.Show("The App is Closing"); // Closes the app this.Close(); } // Event handling that posts the mouse x, y position in title private void Window_MouseMove(object sender, MouseEventArgs e) { Title = e.GetPosition(this).ToString(); } private void BtnOpenFile_Click(object sender, RoutedEventArgs e) { // Opens an open file dialog OpenFileDialog openDlg = new OpenFileDialog(); openDlg.ShowDialog(); } private void BtnSaveFile_Click(object sender, RoutedEventArgs e) { // Opens a save file dialog SaveFileDialog saveDlg = new SaveFileDialog(); saveDlg.ShowDialog(); } private void Send_Button_Click(object sender, RoutedEventArgs e) { //usersName = UsersName.Text; //MessageBox.Show($"Hello {usersName}"); } }} // ---------- MainWindow.xaml ---------- <!-- x:Class defines what code handles events --><!-- You can define the title, size, whether it can resize, Whether it automatically resizes for content, whether it stays on top, whether it starts minimized or maximized, and an icon --><Window x:Class="WpfTut.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfTut" xmlns:sys="clr-namespace:System;assembly=mscorlib" mc:Ignorable="d" Title="Hello WPF" Height="350" Width="525" ResizeMode="NoResize" SizeToContent="WidthAndHeight" Topmost="False" WindowState="Normal" Icon="./Resources/favicon.ico" MouseMove="Window_MouseMove"> <!-- You can store data as a resource and reuse it by adding this xmlns:sys="clr-namespace:System;assembly=mscorlib" --> <Window.Resources> <sys:String x:Key="strHelloAgain">Hello Again</sys:String> <!-- You can define default styling of components --> <Style TargetType="Button"> <Setter Property="Margin" Value="1"/> <Setter Property="FontSize" Value="20"/> <Setter Property="VerticalContentAlignment" Value="Center"/> <Setter Property="FontFamily" Value="Consolas"/> </Style> </Window.Resources> <!-- This is the layout manager of which there are many including Grid, Canvas, and DockPanel --> <StackPanel Orientation="Vertical"> <!-- This is where your content goes --> <TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" Text="Hello World" VerticalAlignment="Top" FontSize="40"/> <!-- Resource used here --> <TextBlock Text="{StaticResource strHelloAgain}" FontSize="40" HorizontalAlignment="Center"/> <!-- This creates a button and calls an event handler --> <!-- You can see a list of all events by clicking the lightning bolt in properties --> <Button x:Name="Button1" Height="40" Width="90" HorizontalAlignment="Center" Content="Close Window" Click="Button1Clicked" /> <!-- Opens the open file dialog --> <Button x:Name="BtnOpenFile" Height="40" Width="90" HorizontalAlignment="Center" Content="Open File" Click="BtnOpenFile_Click" /> <!-- Opens the save file dialog --> <Button x:Name="BtnSaveFile" Height="40" Width="90" HorizontalAlignment="Center" Content="Save File" Click="BtnSaveFile_Click" /> </StackPanel></Window> // ---------- Using Canvas ---------- <!-- This is the Canvas layout manager and it allows you to place components absolutely and they don't dynamically resize --> <Canvas Background="Gray" Height="350" Width="525"> <Label Content="Name" Canvas.Left="10" Canvas.Top="10"/> <TextBox Name="UsersName" Height="23" Canvas.Left="66" TextWrapping="Wrap" Text="Enter name" Canvas.Top="12" Width="159"/> <Button Content="Send" Canvas.Left="242" Canvas.Top="13" Width="75" Click="Send_Button_Click"/> </Canvas> // ---------- Using WrapPanel ---------- <!-- A WrapPanel allows components to flow as the window is resized (Most times a WrapPanel is only used as a subelement <WrapPanel Background="Gray" Orientation="Horizontal"> <Label Content="Name"/> <TextBox Name="UsersName" Text="Enter Name" Width="159"/> <Button Content="Send" Width="75" Click="Send_Button_Click"/> </WrapPanel> --> // ---------- Using Grid ---------- <!-- A Grid Panels are very flexible because everything is placed in a cell in columns and rows You add rows and columns by adding RowDefinitions and ColumnDefinitions that have heights that are fixed, Auto (Takes space needed by component), or * (Takes space available)--> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="*" /> <RowDefinition Height="*" /> <RowDefinition Height="*" /> <RowDefinition Height="*" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <!-- Define where component starts and the number of columns it spans --> <TextBox Grid.Row="0" Grid.Column="0" Margin="2,5" Grid.ColumnSpan="4"/> <Button Content="7" HorizontalAlignment="Left" Grid.Row="1" VerticalAlignment="Top" Width="131" Height="51"/> <Button Content="8" Grid.Column="1" HorizontalAlignment="Left" Grid.Row="1" VerticalAlignment="Top" Width="131" Height="51"/> <Button Content="9" Grid.Column="2" HorizontalAlignment="Left" Grid.Row="1" VerticalAlignment="Top" Width="131" Height="51"/> <Button Content="+" Grid.Column="3" HorizontalAlignment="Left" Grid.Row="1" VerticalAlignment="Top" Width="131" Height="51"/> <Button Content="4" Grid.Column="0" HorizontalAlignment="Left" Grid.Row="2" VerticalAlignment="Top" Width="131" Height="51"/> <Button Content="5" Grid.Column="1" HorizontalAlignment="Left" Grid.Row="2" VerticalAlignment="Top" Width="131" Height="51"/> <Button Content="6" Grid.Column="2" HorizontalAlignment="Left" Grid.Row="2" VerticalAlignment="Top" Width="131" Height="51"/> <Button Content="-" Grid.Column="3" HorizontalAlignment="Left" Grid.Row="2" VerticalAlignment="Top" Width="131" Height="51"/> <Button Content="1" Grid.Column="0" HorizontalAlignment="Left" Grid.Row="3" VerticalAlignment="Top" Width="131" Height="51"/> <Button Content="2" Grid.Column="1" HorizontalAlignment="Left" Grid.Row="3" VerticalAlignment="Top" Width="131" Height="51"/> <Button Content="3" Grid.Column="2" HorizontalAlignment="Left" Grid.Row="3" VerticalAlignment="Top" Width="131" Height="51"/> <Button Content="*" Grid.Column="3" HorizontalAlignment="Left" Grid.Row="3" VerticalAlignment="Top" Width="131" Height="51"/> <Button Content="C" Grid.Column="0" HorizontalAlignment="Left" Grid.Row="4" VerticalAlignment="Top" Width="131" Height="51"/> <Button Content="0" Grid.Column="1" HorizontalAlignment="Left" Grid.Row="4" VerticalAlignment="Top" Width="131" Height="51"/> <Button Content="=" Grid.Column="2" HorizontalAlignment="Left" Grid.Row="4" VerticalAlignment="Top" Width="131" Height="51"/> <Button Content="/" Grid.Column="3" HorizontalAlignment="Left" Grid.Row="4" VerticalAlignment="Top" Width="131" Height="51"/> </Grid> xxxxxxxxxx// ---------- WpfTutorial ---------- // ---------- MainWindow.xaml ---------- <Window x:Class="WpfTutorial.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfTutorial" xmlns:sys="clr-namespace:System;assembly=mscorlib" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525" SizeToContent="WidthAndHeight" Topmost="False" WindowState="Normal" Icon="./Resources/favicon.ico"> <!-- Create a menu bar Put _ before the shortcut key which is triggered with Alt - Whatever --> <!-- 1. Get the Visual Studio Image Library if you want standard icons A. https://www.microsoft.com/en-us/download/details.aspx?id=35825 B. I got VS2013 Image Library.zip --> <DockPanel> <Menu DockPanel.Dock="Top"> <MenuItem Header="_File"> <MenuItem x:Name="menuNew" Header="_New" InputGestureText="Ctrl+N"> <MenuItem.Icon> <Image Source="./Resources/New.bmp" /> </MenuItem.Icon> </MenuItem> <MenuItem x:Name="menuOpen" Header="_Open" InputGestureText="Ctrl+O" Click="MenuOpen_Click"> <MenuItem.Icon> <Image Source="./Resources/Open.bmp" /> </MenuItem.Icon> </MenuItem> <MenuItem x:Name="menuSave" Header="_Save" InputGestureText="Ctrl+S" Click="MenuSave_Click"> <MenuItem.Icon> <Image Source="./Resources/Save.bmp" /> </MenuItem.Icon> </MenuItem> <Separator /> <MenuItem x:Name="menuExit" Header="Exit" InputGestureText="Ctrl+F4" Click="MenuExit_Click"/> </MenuItem> <MenuItem Header="_Edit"> <MenuItem x:Name="menuCut" Header="Cut" Command="ApplicationCommands.Cut" InputGestureText="Ctrl+X"/> <MenuItem x:Name="menuCopy" Header="Copy" Command="ApplicationCommands.Copy" InputGestureText="Ctrl+C"/> <MenuItem x:Name="menuPaste" Header="Paste" Command="ApplicationCommands.Paste" InputGestureText="Ctrl+V"/> <Separator /> <MenuItem Header="_Font" InputGestureText="Ctrl+F"> <MenuItem x:Name="menuFontTimes" Header="Times" IsCheckable="True" StaysOpenOnClick="True" Click="MenuFontTimes_Click"/> <MenuItem x:Name="menuFontCourier" Header="Courier" IsCheckable="True" StaysOpenOnClick="True" Click="MenuFontCourier_Click"/> <MenuItem x:Name="menuFontArial" Header="Arial" IsCheckable="True" StaysOpenOnClick="True" Click="MenuFontArial_Click"/> </MenuItem> </MenuItem> </Menu> <TextBox x:Name="txtBoxDoc" Height="290" Width="500"/> </DockPanel> <!-- You can create rows and columns in the Grid layout by just clicking the borders --> <!-- You can drag a label in a cell, copy and paste some more while changing the margins select them and Group Into -> ScrollViewer <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="153*"/> <ColumnDefinition Width="208*"/> <ColumnDefinition Width="156*"/> </Grid.ColumnDefinitions> <ScrollViewer Grid.Column="2" Margin="0,0,0,193"> <Grid> <Label Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,0,-17,0"/> <Label Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,25,-17,0"/> <Label Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,50,-17,0"/> <Label Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,75,-17,0"/> <Label Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,100,-17,0"/> </Grid> </ScrollViewer> </Grid> --> <!-- A DockPanel is normally used as a container for other panels <DockPanel> <Label x:Name="lblTop" DockPanel.Dock="Top" Content="TOP"/> <Label x:Name="lblLeft" DockPanel.Dock="Left" Content="LEFT"/> <Label x:Name="lblRight" DockPanel.Dock="Right" Content="RIGHT"/> <Label x:Name="lblBottom" DockPanel.Dock="Bottom" Content="BOTTOM"/> <Label x:Name="lblCenter" Content="CENTER"/> </DockPanel> --></Window> // ---------- MainWindow.xaml.cs ---------- using Microsoft.Win32;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes; namespace WpfTutorial{ /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } // Closes the app private void MenuExit_Click(object sender, RoutedEventArgs e) { this.Close(); } // Opens the open dialog private void MenuOpen_Click(object sender, RoutedEventArgs e) { OpenFileDialog openDlg = new OpenFileDialog(); openDlg.ShowDialog(); } // Opens the save dialog private void MenuSave_Click(object sender, RoutedEventArgs e) { SaveFileDialog saveDlg = new SaveFileDialog(); saveDlg.ShowDialog(); } // Unchecks other fonts and changes font for the text box private void MenuFontTimes_Click(object sender, RoutedEventArgs e) { menuFontCourier.IsChecked = false; menuFontArial.IsChecked = false; txtBoxDoc.FontFamily = new FontFamily("Times New Roman"); } private void MenuFontCourier_Click(object sender, RoutedEventArgs e) { menuFontTimes.IsChecked = false; menuFontArial.IsChecked = false; txtBoxDoc.FontFamily = new FontFamily("Courier"); } private void MenuFontArial_Click(object sender, RoutedEventArgs e) { menuFontCourier.IsChecked = false; menuFontTimes.IsChecked = false; txtBoxDoc.FontFamily = new FontFamily("Arial"); } }} xxxxxxxxxx// ---------- WpfTutorial ---------- // ---------- MainWindow.xaml.cs ---------- using Microsoft.Win32;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes; namespace WpfTutorial{ /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void MenuExit_Click(object sender, RoutedEventArgs e) { this.Close(); } private void MenuOpen_Click(object sender, RoutedEventArgs e) { OpenFileDialog openDlg = new OpenFileDialog(); openDlg.ShowDialog(); } private void MenuSave_Click(object sender, RoutedEventArgs e) { SaveFileDialog saveDlg = new SaveFileDialog(); saveDlg.ShowDialog(); } private void MenuFontTimes_Click(object sender, RoutedEventArgs e) { menuFontCourier.IsChecked = false; menuFontArial.IsChecked = false; txtBoxDoc.FontFamily = new FontFamily("Times New Roman"); } private void MenuFontCourier_Click(object sender, RoutedEventArgs e) { menuFontTimes.IsChecked = false; menuFontArial.IsChecked = false; txtBoxDoc.FontFamily = new FontFamily("Courier"); } private void MenuFontArial_Click(object sender, RoutedEventArgs e) { menuFontCourier.IsChecked = false; menuFontTimes.IsChecked = false; txtBoxDoc.FontFamily = new FontFamily("Arial"); } // ---------- NEW STUFF ---------- // Used to track if font size combobox is closed private bool comboFSClosed = true; // Change font size of text box after combo is closed private void ComboFontSize_DropDownClosed(object sender, EventArgs e) { if (comboFSClosed) ChangeTBFontSize(); comboFSClosed = true; } // Verify combo is closed and call for font size change private void ComboFontSize_SelectionChanged(object sender, SelectionChangedEventArgs e) { ComboBox combobox = sender as ComboBox; comboFSClosed = !combobox.IsDropDownOpen; ChangeTBFontSize(); } private void ChangeTBFontSize() { // Convert combo font size data to string string fontsize = comboFontSize.SelectedItem.ToString(); // Get the last 2 numbers fontsize = fontsize.Substring(fontsize.Length - 2); switch (fontsize) { case "10": txtBoxDoc.FontSize = 10; break; case "12": txtBoxDoc.FontSize = 12; break; case "14": txtBoxDoc.FontSize = 14; break; case "16": txtBoxDoc.FontSize = 16; break; } } }} // ---------- MainWindow.xaml ---------- <Window x:Class="WpfTutorial.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfTutorial" xmlns:sys="clr-namespace:System;assembly=mscorlib" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525" SizeToContent="WidthAndHeight" Topmost="False" WindowState="Normal" Icon="./Resources/favicon.ico"> <DockPanel> <Menu DockPanel.Dock="Top"> <MenuItem Header="_File"> <MenuItem x:Name="menuNew" Header="_New" InputGestureText="Ctrl+N"> <MenuItem.Icon> <Image Source="./Resources/New.bmp"/> </MenuItem.Icon> </MenuItem> <MenuItem x:Name="menuOpen" Header="_Open" InputGestureText="Ctrl+O" Click="MenuOpen_Click"> <MenuItem.Icon> <Image Source="./Resources/Open.bmp"/> </MenuItem.Icon> </MenuItem> <MenuItem x:Name="menuSave" Header="_Save" InputGestureText="Ctrl+S" Click="MenuSave_Click"> <MenuItem.Icon> <Image Source="./Resources/Save.bmp"/> </MenuItem.Icon> </MenuItem> <MenuItem x:Name="menuExit" Header="Exit" Click="MenuExit_Click"> </MenuItem> </MenuItem> <MenuItem Header="_Edit"> <MenuItem x:Name="menuCut" Header="Cut" Command="ApplicationCommands.Cut" InputGestureText="Ctrl+X"/> <MenuItem x:Name="menuCopy" Header="Copy" Command="ApplicationCommands.Copy" InputGestureText="Ctrl+C"/> <MenuItem x:Name="menuPaste" Header="Paste" Command="ApplicationCommands.Paste" InputGestureText="Ctrl+V"/> <Separator /> <MenuItem Header="_Font" InputGestureText="Ctrl+F"> <MenuItem x:Name="menuFontTimes" Header="Times" IsCheckable="True" StaysOpenOnClick="True" Click="MenuFontTimes_Click"/> <MenuItem x:Name="menuFontCourier" Header="Courier" IsCheckable="True" StaysOpenOnClick="True" Click="MenuFontCourier_Click"/> <MenuItem x:Name="menuFontArial" Header="Arial" IsCheckable="True" StaysOpenOnClick="True" Click="MenuFontArial_Click"/> </MenuItem> </MenuItem> </Menu> <!-- ---------- NEW STUFF ---------- --> <!-- A toolbar provides quick access to tools --> <!-- You can also dock on the left or right DockPanel.Dock="Right" Orientation="Vertical" --> <ToolBarTray DockPanel.Dock="Top"> <ToolBar> <Button x:Name="tbOpen" ToolTip="Open File" Click="MenuOpen_Click"> <Image Source="./Resources/Open.bmp"></Image> </Button> <Button x:Name="tbSave" ToolTip="Save File" Click="MenuSave_Click"> <Image Source="./Resources/Save.bmp"></Image> </Button> <Button x:Name="tbCut" Command="ApplicationCommands.Cut"> <Image Source="./Resources/Cut.bmp"></Image> </Button> <Button x:Name="tbCopy" Command="ApplicationCommands.Copy"> <Image Source="./Resources/Copy.bmp"></Image> </Button> <Button x:Name="tbPaste" Command="ApplicationCommands.Paste"> <Image Source="./Resources/Paste.bmp"></Image> </Button> <Separator /> <Label>Font size:</Label> <ComboBox x:Name="comboFontSize" SelectionChanged="ComboFontSize_SelectionChanged" DropDownClosed="ComboFontSize_DropDownClosed"> <ComboBoxItem>10</ComboBoxItem> <ComboBoxItem IsSelected="True">12</ComboBoxItem> <ComboBoxItem>14</ComboBoxItem> <ComboBoxItem>16</ComboBoxItem> </ComboBox> </ToolBar> </ToolBarTray> <TextBox x:Name="txtBoxDoc" Height="290" Width="500" FontSize="12"/> </DockPanel> </Window> xxxxxxxxxx// ---------- MainWindow.xaml ---------- <Window x:Class="WpfTutorial.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfTutorial" xmlns:sys="clr-namespace:System;assembly=mscorlib" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525" SizeToContent="WidthAndHeight" Topmost="False" WindowState="Normal" Icon="./Resources/favicon.ico"> <Grid> <!-- You can add more tabs by right clicking the top of the tabs and select Add Tab --> <TabControl Height="319" VerticalAlignment="Top" Width="515"> <TabItem Header="Calendar"> <Grid Background="#FFE5E5E5"> <!-- Drag a Calendar and TextBox on a tab You can customize the calendar --> <Calendar Name="MyCalendar" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Height="171" Width="184" Background="AliceBlue" DisplayMode="Month" DisplayDateStart="3/1/2017" DisplayDateEnd="3/31/2017" FirstDayOfWeek="Monday" IsTodayHighlighted="True" SelectedDatesChanged="MyCalendar_SelectedDatesChanged" > <!-- You can X out date ranges --> <Calendar.BlackoutDates> <CalendarDateRange Start="3/1/2017" End="3/8/2017"/> </Calendar.BlackoutDates> <Calendar.SelectedDates> <sys:DateTime>3/25/2017</sys:DateTime> </Calendar.SelectedDates> </Calendar> <TextBox Name="tbDateSelected" HorizontalAlignment="Left" Height="23" Margin="227,14,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/> </Grid> </TabItem> <TabItem Header="Draw" KeyUp="DrawPanel_KeyUp"> <!-- Open your Document outline on the left and change the tab layout type from Grid to StackPanel --> <StackPanel Background="#FFE5E5E5" Margin="0,-2,0,2"> <!-- Click toolbar and in Properties -> Common -> Items and add 3 radio buttons for Common -> Content name them Draw, Erase, and Select Set border brush RGB to 210 each and change width to 80 and height to 50 Select all buttons with Shift and then change the GroupName in properties to DrawGroup Right click the Toolbox -> Choose Items -> put a check in InkCanvas Drag an InkCanvas on your tab Add the same click event name to buttons DrawButton_Click --> <ToolBar Name="drawingToolbar" Height="50"> <RadioButton Name="DrawButton" Click="DrawButton_Click" BorderBrush="#FFD2D2D2" Content="Draw" Height="50" Width="80" GroupName="DrawGroup"/> <RadioButton Name="EraseButton" Click="DrawButton_Click" BorderBrush="#FFD2D2D2" Content="Erase" Height="50" Width="80" GroupName="DrawGroup"/> <RadioButton Name="SelectButton" Click="DrawButton_Click" BorderBrush="#FFD2D2D2" Content="Select" Height="50" Width="80" GroupName="DrawGroup"/> <Button BorderBrush="#FFD2D2D2" Content="Save" Height="50" Width="80" Click="SaveButton_Click"/> <Button BorderBrush="#FFD2D2D2" Content="Open" Height="50" Width="80" Click="OpenButton_Click"/> </ToolBar> <InkCanvas Name="DrawingCanvas" Height="241"> <InkCanvas.DefaultDrawingAttributes> <DrawingAttributes x:Name="strokeAttr" Width="3" Height="3" Color="black"/> </InkCanvas.DefaultDrawingAttributes> </InkCanvas> </StackPanel> </TabItem> <TabItem Header="TabItem" HorizontalAlignment="Left" Height="20" VerticalAlignment="Top" Width="54"> <Grid Background="#FFE5E5E5"/> </TabItem> <TabItem Header="TabItem" HorizontalAlignment="Left" Height="20" VerticalAlignment="Top" Width="54"> <Grid Background="#FFE5E5E5"/> </TabItem> </TabControl> </Grid> </Window> // ---------- MainWindow.xaml.cs ---------- using Microsoft.Win32;using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Ink;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes; namespace WpfTutorial{ /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void MyCalendar_SelectedDatesChanged(object sender, SelectionChangedEventArgs e) { // Get a reference to the calendar var calendar = sender as Calendar; // Check that it has a value if (calendar.SelectedDate.HasValue) { // Display the date DateTime date = calendar.SelectedDate.Value; try { tbDateSelected.Text = date.ToShortDateString(); } catch (NullReferenceException) { // Needed for a bug that is triggered during // initialization } } } private void DrawButton_Click(object sender, RoutedEventArgs e) { // Get a reference to the radiobutton var radiobutton = sender as RadioButton; // Get the radiobutton pressed string radioBPressed = radiobutton.Content.ToString(); // Change settings based on button if(radioBPressed == "Draw") { this.DrawingCanvas.EditingMode = InkCanvasEditingMode.Ink; } else if(radioBPressed == "Erase") { this.DrawingCanvas.EditingMode = InkCanvasEditingMode.EraseByStroke; } else if(radioBPressed == "Select") { this.DrawingCanvas.EditingMode = InkCanvasEditingMode.Select; } } private void DrawPanel_KeyUp(object sender, KeyEventArgs e) { if ((int)e.Key >= 35 && (int)e.Key <= 68) { switch ((int)e.Key) { case 35: strokeAttr.Width = 2; strokeAttr.Height = 2; break; case 36: strokeAttr.Width = 4; strokeAttr.Height = 4; break; case 37: strokeAttr.Width = 6; strokeAttr.Height = 6; break; case 38: strokeAttr.Width = 8; strokeAttr.Height = 8; break; case 39: strokeAttr.Width = 10; strokeAttr.Height = 10; break; case 40: strokeAttr.Width = 12; strokeAttr.Height = 12; break; case 41: strokeAttr.Width = 14; strokeAttr.Height = 14; break; case 42: strokeAttr.Width = 16; strokeAttr.Height = 16; break; case 43: strokeAttr.Width = 18; strokeAttr.Height = 18; break; case 45: strokeAttr.Color = (Color)ColorConverter.ConvertFromString("Blue"); break; case 50: strokeAttr.Color = (Color)ColorConverter.ConvertFromString("Green"); break; case 68: strokeAttr.Color = (Color)ColorConverter.ConvertFromString("Yellow"); break; } } } private void SaveButton_Click(object sender, RoutedEventArgs e) { using(FileStream fs = new FileStream("MyPicture.bin", FileMode.Create)) { this.DrawingCanvas.Strokes.Save(fs); } } private void OpenButton_Click(object sender, RoutedEventArgs e) { using (FileStream fs = new FileStream("MyPicture.bin", FileMode.Open, FileAccess.Read)) { StrokeCollection sc = new StrokeCollection(fs); this.DrawingCanvas.Strokes = sc; } } }} xxxxxxxxxx// ---------- MainWindow.xaml ---------- <!-- We'll use the Document API layout managers to work with formatted documents using the XML Paper Specification (XPS) --> <!-- Different layout managers FlowDocumentReader : Read only with zoom, search RichTextBox : Displays editable data in a FlowDocument FlowDocumentPageViewer : Shows pages, but no zoom or search--> <TabItem Header="Flow Reader" HorizontalAlignment="Left" Height="20" VerticalAlignment="Top" Width="78"> <Grid Background="#FFE5E5E5"> <!-- ViewingMode : Page, Scroll, TwoPage --> <FlowDocumentReader ViewingMode="Page" IsFindEnabled="True" IsPageViewEnabled="True" IsScrollViewEnabled="True" IsTwoPageViewEnabled="True"> <FlowDocument> <Paragraph> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </Paragraph> <List> <ListItem> <Paragraph>Item 1</Paragraph> </ListItem> <ListItem> <Paragraph>Item 2</Paragraph> </ListItem> </List> <BlockUIContainer> <StackPanel> <Image Source=".\Resources\Turtle.png" Height="64"/> <Label Foreground="Blue">Favorite Phone :</Label> <ComboBox> <ComboBoxItem IsSelected="True">Android</ComboBoxItem> <ComboBoxItem>Apple</ComboBoxItem> <ComboBoxItem>Black Berry</ComboBoxItem> </ComboBox> <Label Foreground ="Red">Favorite Color:</Label> <StackPanel> <RadioButton>Red</RadioButton> <RadioButton>Green</RadioButton> <RadioButton>Blue</RadioButton> </StackPanel> <Label>Your Name:</Label> <TextBox> Name </TextBox> </StackPanel> </BlockUIContainer> <!-- Put here to make an empty line --> <Paragraph></Paragraph> <Table> <Table.Columns> <TableColumn /> <TableColumn /> <TableColumn /> </Table.Columns> <TableRowGroup> <TableRow> <TableCell ColumnSpan="3" Background="Blue" Foreground="AliceBlue"> <Paragraph Padding="10">Best Baseball Players</Paragraph> </TableCell> </TableRow> <TableRow> <TableCell Background="White"> <Paragraph>Name</Paragraph> </TableCell> <TableCell Background="White"> <Paragraph>Average</Paragraph> </TableCell> <TableCell Background="White"> <Paragraph>HRs</Paragraph> </TableCell> </TableRow> </TableRowGroup> </Table> </FlowDocument> </FlowDocumentReader> </Grid> </TabItem> <TabItem Header="Page Viewer" HorizontalAlignment="Left" Height="20" VerticalAlignment="Top" Width="84"> <StackPanel Background="#FFE5E5E5"> <FlowDocumentPageViewer Name="FdPageViewer" Height="291"> <FlowDocument> <Paragraph> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </Paragraph> <Paragraph> Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? </Paragraph> </FlowDocument> </FlowDocumentPageViewer> </StackPanel> </TabItem> <TabItem Header="Scroll" HorizontalAlignment="Left" Height="20" VerticalAlignment="Top" Width="54"> <Grid Background="#FFE5E5E5"> <FlowDocumentScrollViewer> <FlowDocument> <Paragraph> Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur </Paragraph> </FlowDocument> </FlowDocumentScrollViewer> </Grid> </TabItem> <TabItem Header="Generate" HorizontalAlignment="Left" Height="20" VerticalAlignment="Top" Width="64"> <Grid Background="#FFE5E5E5"> <FlowDocumentScrollViewer Name="fdScrollViewer" /> </Grid> </TabItem> <TabItem Header="Rich" HorizontalAlignment="Left" Height="20" VerticalAlignment="Top" Width="54"> <!-- You place a FlowDocument in a RichTextBox and it can be edited. You can add spell checking and a menu for cut, copy and paste --> <StackPanel> <RichTextBox Name="RichTB" Height="200" SpellCheck.IsEnabled="True" ContextMenuOpening="RichTB_ContextMenuOpening"> <FlowDocument> <Paragraph> You can edit me </Paragraph> </FlowDocument> </RichTextBox> <Button Click="SaveRTBContent">Save</Button> <Button Click="LoadRTBContent">Open</Button> </StackPanel> </TabItem> // ---------- MainWindow.xaml.cs ---------- private void GenerateDoc() { FlowDocument doc = new FlowDocument(); Paragraph para = new Paragraph(new Run("Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?")); doc.Blocks.Add(para); para = new Paragraph(new Run("Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?")) { FontSize = 14, FontStyle = FontStyles.Italic, Foreground = Brushes.Green }; doc.Blocks.Add(para); fdScrollViewer.Document = doc; } // A ContextMenu displays Cut, Copy and Paste commands private void RichTB_ContextMenuOpening(object sender, ContextMenuEventArgs e) { // Convert to a RichTextBox and check for null RichTextBox rtb = sender as RichTextBox; if (rtb == null) return; // Create ContextMenu ContextMenu contextMenu = rtb.ContextMenu; contextMenu.PlacementTarget = rtb; // This will place the menu at the point where // it is right clicked contextMenu.Placement = PlacementMode.RelativePoint; // Place the menu to the right of the click TextPointer position = rtb.Selection.End; if (position == null) return; // Create the menu Rect positionRect = position.GetCharacterRect(LogicalDirection.Forward); contextMenu.HorizontalOffset = positionRect.X; contextMenu.VerticalOffset = positionRect.Y; // Finally, mark the event as handled contextMenu.IsOpen = true; e.Handled = true; } void SaveRTBContent(Object sender, RoutedEventArgs args) { // Defines the range of text to save TextRange range = new TextRange(RichTB.Document.ContentStart, RichTB.Document.ContentEnd); // Create a stream to write to the file FileStream fStream = new FileStream("C:\\Users\\derekbanas\\C#Data\\test.xaml", FileMode.Create); // Save the content range.Save(fStream, DataFormats.XamlPackage); fStream.Close(); } // Load text into RichTextBox void LoadRTBContent(Object sender, RoutedEventArgs args) { TextRange range; FileStream fStream; if (File.Exists("C:\\Users\\derekbanas\\C#Data\\test.xaml")) { range = new TextRange(RichTB.Document.ContentStart, RichTB.Document.ContentEnd); fStream = new FileStream("C:\\Users\\derekbanas\\C#Data\\test.xaml", FileMode.OpenOrCreate); range.Load(fStream, DataFormats.XamlPackage); fStream.Close(); } } xxxxxxxxxx// ---------- MainWindow.xaml ---------- <Window x:Class="WpfTutorial.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfTutorial" xmlns:sys="clr-namespace:System;assembly=mscorlib" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525" SizeToContent="WidthAndHeight" Topmost="False" WindowState="Normal" Icon="./Resources/favicon.ico"> <DockPanel> <!-- Click the toolbar and select Common -> Items -> ... Set Border Brush RGB to 150 Height to 50 and Width to 80 Add a Content name for Line, Ellipse and Rectangle for each Select all radiobuttons and give the group name ShapeGroup --> <ToolBar Name="MyToolbar" DockPanel.Dock="Top" Height="50"> <RadioButton Name="LineButton" BorderBrush="#FF969696" Content="Line" Height="50" Width="77" GroupName="ShapeGroup" Click="LineButton_Click" IsChecked="True"/> <RadioButton Name="EllipseButton" BorderBrush="#FF969696" Content="Ellipse" Height="50" Width="80" GroupName="ShapeGroup" Click="EllipseButton_Click"/> <RadioButton Name="RectangleButton" BorderBrush="#FF969696" Content="Rectangle" Height="50" Width="80" GroupName="ShapeGroup" Click="RectangleButton_Click"/> </ToolBar> <Canvas Name="MyCanvas" Background="AntiqueWhite" Height="300" Width="525" MouseDown="MyCanvas_MouseDown" MouseUp="MyCanvas_MouseUp" MouseMove="MyCanvas_MouseMove"> <!-- Draw a line --> <Line X1="10" Y1="10" X2="50" Y2="50" Stroke="Black" StrokeThickness="4" /> <!-- Draw an Ellipse --> <Ellipse Fill="Yellow" Height="50" Width="100" StrokeThickness="2" Stroke="Black" Canvas.Left="100" Canvas.Top="20"/> <!-- Draw a Rectangle --> <Rectangle Fill="Blue" Height="50" Width="100" Canvas.Left="240" Canvas.Top="20"/> </Canvas> </DockPanel> </Window> // ---------- MainWindow.xaml.cs ---------- using Microsoft.Win32;using System;using System.Collections.Generic;using System.IO;using System.Windows;using System.Windows.Controls;using System.Windows.Input;using System.Windows.Media;using System.Windows.Shapes; namespace WpfTutorial{ /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> // For generating a limited number of 2D // vector images you can use // System.Windows.Shapes // Shapes created this way respond to // events like other WPF components public partial class MainWindow : Window { // Define enum for all 3 shapes private enum MyShape { Line, Ellipse, Rectangle } // Define the current shape used private MyShape currShape; public MainWindow() { InitializeComponent(); } private void LineButton_Click(object sender, RoutedEventArgs e) { currShape = MyShape.Line; } private void EllipseButton_Click(object sender, RoutedEventArgs e) { currShape = MyShape.Ellipse; } private void RectangleButton_Click(object sender, RoutedEventArgs e) { currShape = MyShape.Rectangle; } Point start; Point end; private void MyCanvas_MouseDown(object sender, MouseButtonEventArgs e) { // Get the X & Y of where mouse is 1st clicked start = e.GetPosition(this); } private void MyCanvas_MouseUp(object sender, MouseButtonEventArgs e) { // Draw the correct shape switch (currShape) { case MyShape.Line: DrawLine(); break; case MyShape.Ellipse: DrawEllipse(); break; case MyShape.Rectangle: DrawRectangle(); break; default: return; } } private void MyCanvas_MouseMove(object sender, MouseEventArgs e) { // Update the X & Y as the mouse moves if (e.LeftButton == MouseButtonState.Pressed) { end = e.GetPosition(this); } } // Sets and draws line after mouse is released private void DrawLine() { Line newLine = new Line() { Stroke = Brushes.Blue, X1 = start.X, Y1 = start.Y - 50, X2 = end.X, Y2 = end.Y - 50 }; MyCanvas.Children.Add(newLine); } // Sets and draws ellipse after mouse is released private void DrawEllipse() { Ellipse newEllipse = new Ellipse() { Stroke = Brushes.Green, Fill = Brushes.Red, StrokeThickness = 4, Height = 10, Width = 10 }; // If the user the user tries to draw from // any direction then down and to the right // you'll get an error unless you use if // to change Left & TopProperty and Height // and Width accordingly if (end.X >= start.X) { // Defines the left part of the ellipse newEllipse.SetValue(Canvas.LeftProperty, start.X); newEllipse.Width = end.X - start.X; } else { newEllipse.SetValue(Canvas.LeftProperty, end.X); newEllipse.Width = start.X - end.X; } if (end.Y >= start.Y) { // Defines the top part of the ellipse newEllipse.SetValue(Canvas.TopProperty, start.Y - 50); newEllipse.Height = end.Y - start.Y; } else { newEllipse.SetValue(Canvas.TopProperty, end.Y - 50); newEllipse.Height = start.Y - end.Y; } MyCanvas.Children.Add(newEllipse); } // Sets and draws rectangle after mouse is released private void DrawRectangle() { Rectangle newRectangle = new Rectangle() { Stroke = Brushes.Orange, Fill = Brushes.Blue, StrokeThickness = 4 }; if (end.X >= start.X) { // Defines the left part of the rectangle newRectangle.SetValue(Canvas.LeftProperty, start.X); newRectangle.Width = end.X - start.X; } else { newRectangle.SetValue(Canvas.LeftProperty, end.X); newRectangle.Width = start.X - end.X; } if (end.Y >= start.Y) { // Defines the top part of the rectangle newRectangle.SetValue(Canvas.TopProperty, start.Y - 50); newRectangle.Height = end.Y - start.Y; } else { newRectangle.SetValue(Canvas.TopProperty, end.Y - 50); newRectangle.Height = start.Y - end.Y; } MyCanvas.Children.Add(newRectangle); } }} xxxxxxxxxx----- App.config ----- <?xml version="1.0" encoding="utf-8" ?><configuration> <appSettings> <add key="provider" value="System.Data.SqlClient" /> <add key="connectionString" value="Data Source=DEREKBANAS936E;Initial Catalog=StoreDB;Integrated Security=True;Pooling=False"/> </appSettings> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> </startup></configuration> ----- Program.cs ----- using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; using System.Data.Common;using System.Configuration; namespace DBTest{ class Program { static void Main(string[] args) { // App.config stores configuration data // System.Data.SqlClient provides classes // for accessing a SQL Server DB // connectionString defines the DB name, and // other parameters for connecting to the DB // Configurationmanager provides access to // config data in App.config string provider = ConfigurationManager.AppSettings["provider"]; string connectionString = ConfigurationManager.AppSettings["connectionString"]; // DbProviderFactories generates an // instance of a DbProviderFactory DbProviderFactory factory = DbProviderFactories.GetFactory(provider); // The DBConnection represents the DB connection using (DbConnection connection = factory.CreateConnection()) { // Check if a connection was made if(connection == null) { Console.WriteLine("Connection Error"); Console.ReadLine(); return; } // The DB data needed to open the correct DB connection.ConnectionString = connectionString; // Open the DB connection connection.Open(); // Allows you to pass queries to the DB DbCommand command = factory.CreateCommand(); if(command == null) { Console.WriteLine("Command Error"); Console.ReadLine(); return; } // Set the DB connection for commands command.Connection = connection; // The query you want to issue command.CommandText = "Select * From Products"; // DbDataReader reads the row results // from the query using (DbDataReader dataReader = command.ExecuteReader()) { // Advance to the next results while (dataReader.Read()) { // Output results using row names Console.WriteLine($"{dataReader["ProdId"]} " + $"{dataReader["Product"]}"); } } Console.ReadLine(); } } }}